From c601b5a27f74b16158adafe429faefbe573e64a2 Mon Sep 17 00:00:00 2001 From: Szymon Tomasz Stefanek Date: Sat, 1 Jan 2011 20:19:56 +0000 Subject: The big rename for modules. Still some details remaining. git-svn-id: https://svn.kvirc.de/svn/trunk/kvirc@5284 17fca916-40b9-46aa-a4ea-0a15b648b75c --- src/modules/about/AboutDialog.cpp | 246 ++ src/modules/about/AboutDialog.h | 41 + src/modules/about/CMakeLists.txt | 4 +- src/modules/about/aboutdialog.cpp | 246 -- src/modules/about/aboutdialog.h | 41 - src/modules/about/libkviabout.cpp | 6 +- src/modules/actioneditor/ActionEditor.cpp | 939 +++++ src/modules/actioneditor/ActionEditor.h | 204 ++ src/modules/actioneditor/CMakeLists.txt | 4 +- src/modules/actioneditor/actioneditor.cpp | 939 ----- src/modules/actioneditor/actioneditor.h | 204 -- src/modules/actioneditor/libkviactioneditor.cpp | 6 +- src/modules/addon/AddonFunctions.cpp | 272 ++ src/modules/addon/AddonFunctions.h | 42 + src/modules/addon/CMakeLists.txt | 6 +- src/modules/addon/PackAddonDialog.cpp | 664 ++++ src/modules/addon/PackAddonDialog.h | 252 ++ src/modules/addon/addonfunctions.cpp | 272 -- src/modules/addon/addonfunctions.h | 42 - src/modules/addon/libkviaddon.cpp | 10 +- src/modules/addon/managementdialog.cpp | 62 +- src/modules/addon/managementdialog.h | 16 +- src/modules/addon/packaddondialog.cpp | 664 ---- src/modules/addon/packaddondialog.h | 252 -- src/modules/aliaseditor/AliasEditorWindow.cpp | 1247 +++++++ src/modules/aliaseditor/AliasEditorWindow.h | 190 + src/modules/aliaseditor/CMakeLists.txt | 4 +- src/modules/aliaseditor/aliaseditor.cpp | 1247 ------- src/modules/aliaseditor/aliaseditor.h | 190 - src/modules/aliaseditor/libkvialiaseditor.cpp | 6 +- src/modules/channelsjoin/CMakeLists.txt | 4 +- src/modules/channelsjoin/ChannelsJoinDialog.cpp | 413 +++ src/modules/channelsjoin/ChannelsJoinDialog.h | 162 + src/modules/channelsjoin/channelsjoinwindow.cpp | 413 --- src/modules/channelsjoin/channelsjoinwindow.h | 162 - src/modules/channelsjoin/libkvichannelsjoin.cpp | 6 +- src/modules/classeditor/CMakeLists.txt | 4 +- src/modules/classeditor/ClassEditorWindow.cpp | 2101 +++++++++++ src/modules/classeditor/ClassEditorWindow.h | 639 ++++ src/modules/classeditor/classeditor.cpp | 2101 ----------- src/modules/classeditor/classeditor.h | 639 ---- src/modules/classeditor/libkviclasseditor.cpp | 6 +- src/modules/codetester/CMakeLists.txt | 4 +- src/modules/codetester/CodeTesterWindow.cpp | 141 + src/modules/codetester/CodeTesterWindow.h | 69 + src/modules/codetester/codetester.cpp | 141 - src/modules/codetester/codetester.h | 69 - src/modules/codetester/libkvicodetester.cpp | 10 +- src/modules/dcc/CMakeLists.txt | 46 +- src/modules/dcc/DccBroker.cpp | 994 ++++++ src/modules/dcc/DccBroker.h | 123 + src/modules/dcc/DccCanvasWindow.cpp | 301 ++ src/modules/dcc/DccCanvasWindow.h | 69 + src/modules/dcc/DccChatWindow.cpp | 893 +++++ src/modules/dcc/DccChatWindow.h | 106 + src/modules/dcc/DccDescriptor.cpp | 231 ++ src/modules/dcc/DccDescriptor.h | 158 + src/modules/dcc/DccDialog.cpp | 226 ++ src/modules/dcc/DccDialog.h | 83 + src/modules/dcc/DccFileTransfer.cpp | 2248 ++++++++++++ src/modules/dcc/DccFileTransfer.h | 256 ++ src/modules/dcc/DccMarshal.cpp | 657 ++++ src/modules/dcc/DccMarshal.h | 116 + src/modules/dcc/DccThread.cpp | 114 + src/modules/dcc/DccThread.h | 81 + src/modules/dcc/DccUtils.cpp | 170 + src/modules/dcc/DccUtils.h | 36 + src/modules/dcc/DccVideoWindow.cpp | 1032 ++++++ src/modules/dcc/DccVideoWindow.h | 158 + src/modules/dcc/DccVoiceAdpcmCodec.cpp | 306 ++ src/modules/dcc/DccVoiceAdpcmCodec.h | 73 + src/modules/dcc/DccVoiceCodec.cpp | 327 ++ src/modules/dcc/DccVoiceCodec.h | 108 + src/modules/dcc/DccVoiceGsmCodec.cpp | 148 + src/modules/dcc/DccVoiceGsmCodec.h | 56 + src/modules/dcc/DccVoiceWindow.cpp | 1033 ++++++ src/modules/dcc/DccVoiceWindow.h | 443 +++ src/modules/dcc/DccWindow.cpp | 58 + src/modules/dcc/DccWindow.h | 50 + src/modules/dcc/adpcmcodec.cpp | 306 -- src/modules/dcc/adpcmcodec.h | 73 - src/modules/dcc/broker.cpp | 994 ------ src/modules/dcc/broker.h | 123 - src/modules/dcc/canvas.cpp | 301 -- src/modules/dcc/canvas.h | 69 - src/modules/dcc/canvaswidget.cpp | 10 +- src/modules/dcc/canvaswidget.h | 14 +- src/modules/dcc/chat.cpp | 893 ----- src/modules/dcc/chat.h | 106 - src/modules/dcc/codec.cpp | 327 -- src/modules/dcc/codec.h | 108 - src/modules/dcc/descriptor.cpp | 231 -- src/modules/dcc/descriptor.h | 158 - src/modules/dcc/dialogs.cpp | 226 -- src/modules/dcc/dialogs.h | 83 - src/modules/dcc/gsmcodec.cpp | 148 - src/modules/dcc/gsmcodec.h | 56 - src/modules/dcc/libkvidcc.cpp | 120 +- src/modules/dcc/marshal.cpp | 657 ---- src/modules/dcc/marshal.h | 116 - src/modules/dcc/requests.cpp | 38 +- src/modules/dcc/send.cpp | 2248 ------------ src/modules/dcc/send.h | 256 -- src/modules/dcc/thread.cpp | 114 - src/modules/dcc/thread.h | 81 - src/modules/dcc/utils.cpp | 170 - src/modules/dcc/utils.h | 36 - src/modules/dcc/video.cpp | 1032 ------ src/modules/dcc/video.h | 158 - src/modules/dcc/voice.cpp | 1033 ------ src/modules/dcc/voice.h | 443 --- src/modules/dcc/window.cpp | 58 - src/modules/dcc/window.h | 50 - src/modules/editor/CMakeLists.txt | 4 +- src/modules/editor/ScriptEditorImplementation.cpp | 1137 ++++++ src/modules/editor/ScriptEditorImplementation.h | 219 ++ src/modules/editor/libkvieditor.cpp | 10 +- src/modules/editor/scripteditor.cpp | 1137 ------ src/modules/editor/scripteditor.h | 219 -- src/modules/eventeditor/CMakeLists.txt | 4 +- src/modules/eventeditor/EventEditorWindow.cpp | 605 ++++ src/modules/eventeditor/EventEditorWindow.h | 136 + src/modules/eventeditor/eventeditor.cpp | 605 ---- src/modules/eventeditor/eventeditor.h | 136 - src/modules/eventeditor/libkvieventeditor.cpp | 6 +- src/modules/filetransferwindow/CMakeLists.txt | 4 +- .../filetransferwindow/FileTransferWindow.cpp | 866 +++++ .../filetransferwindow/FileTransferWindow.h | 139 + .../filetransferwindow/filetransferwindow.cpp | 866 ----- .../filetransferwindow/filetransferwindow.h | 139 - .../libkvifiletransferwindow.cpp | 6 +- src/modules/help/CMakeLists.txt | 12 +- src/modules/help/HelpIndex.cpp | 602 ++++ src/modules/help/HelpIndex.h | 139 + src/modules/help/HelpWidget.cpp | 137 + src/modules/help/HelpWidget.h | 64 + src/modules/help/HelpWindow.cpp | 322 ++ src/modules/help/HelpWindow.h | 87 + src/modules/help/helpwidget.cpp | 137 - src/modules/help/helpwidget.h | 64 - src/modules/help/helpwindow.cpp | 322 -- src/modules/help/helpwindow.h | 87 - src/modules/help/index.cpp | 602 ---- src/modules/help/index.h | 139 - src/modules/help/libkvihelp.cpp | 24 +- src/modules/http/CMakeLists.txt | 4 +- src/modules/http/HttpFileTransfer.cpp | 493 +++ src/modules/http/HttpFileTransfer.h | 99 + src/modules/http/httpfiletransfer.cpp | 493 --- src/modules/http/httpfiletransfer.h | 99 - src/modules/http/libkvihttp.cpp | 10 +- src/modules/links/CMakeLists.txt | 4 +- src/modules/links/LinksWindow.cpp | 493 +++ src/modules/links/LinksWindow.h | 99 + src/modules/links/libkvilinks.cpp | 8 +- src/modules/links/linkswindow.cpp | 493 --- src/modules/links/linkswindow.h | 99 - src/modules/list/CMakeLists.txt | 4 +- src/modules/list/ListWindow.cpp | 590 ++++ src/modules/list/ListWindow.h | 124 + src/modules/list/libkvilist.cpp | 8 +- src/modules/list/listwindow.cpp | 590 ---- src/modules/list/listwindow.h | 124 - src/modules/logview/CMakeLists.txt | 6 +- src/modules/logview/LogViewWidget.cpp | 102 + src/modules/logview/LogViewWidget.h | 77 + src/modules/logview/LogViewWindow.cpp | 567 +++ src/modules/logview/LogViewWindow.h | 153 + src/modules/logview/libkvilogview.cpp | 8 +- src/modules/logview/logviewmdiwindow.cpp | 567 --- src/modules/logview/logviewmdiwindow.h | 153 - src/modules/logview/logviewwidget.cpp | 102 - src/modules/logview/logviewwidget.h | 77 - src/modules/mediaplayer/CMakeLists.txt | 12 +- src/modules/mediaplayer/MpAmipInterface.cpp | 415 +++ src/modules/mediaplayer/MpAmipInterface.h | 81 + src/modules/mediaplayer/MpInterface.cpp | 275 ++ src/modules/mediaplayer/MpInterface.h | 238 ++ src/modules/mediaplayer/MpMp3.cpp | 458 +++ src/modules/mediaplayer/MpMp3.h | 137 + src/modules/mediaplayer/MpMprisInterface.cpp | 579 +++ src/modules/mediaplayer/MpMprisInterface.h | 135 + src/modules/mediaplayer/MpWinampInterface.cpp | 570 +++ src/modules/mediaplayer/MpWinampInterface.h | 76 + src/modules/mediaplayer/MpXmmsInterface.cpp | 358 ++ src/modules/mediaplayer/MpXmmsInterface.h | 86 + src/modules/mediaplayer/libkvimediaplayer.cpp | 62 +- src/modules/mediaplayer/mp_amipinterface.cpp | 415 --- src/modules/mediaplayer/mp_amipinterface.h | 81 - src/modules/mediaplayer/mp_interface.cpp | 275 -- src/modules/mediaplayer/mp_interface.h | 238 -- src/modules/mediaplayer/mp_mp3.cpp | 458 --- src/modules/mediaplayer/mp_mp3.h | 137 - src/modules/mediaplayer/mp_mprisinterface.cpp | 579 --- src/modules/mediaplayer/mp_mprisinterface.h | 135 - src/modules/mediaplayer/mp_winampinterface.cpp | 570 --- src/modules/mediaplayer/mp_winampinterface.h | 76 - src/modules/mediaplayer/mp_xmmsinterface.cpp | 358 -- src/modules/mediaplayer/mp_xmmsinterface.h | 86 - src/modules/my/CMakeLists.txt | 8 +- src/modules/my/Idle.cpp | 135 + src/modules/my/Idle.h | 85 + src/modules/my/Idle_mac.cpp | 162 + src/modules/my/Idle_win.cpp | 109 + src/modules/my/Idle_x11.cpp | 96 + src/modules/my/idle.cpp | 135 - src/modules/my/idle.h | 85 - src/modules/my/idle_mac.cpp | 162 - src/modules/my/idle_win.cpp | 109 - src/modules/my/idle_x11.cpp | 96 - src/modules/my/libkvimy.cpp | 2 +- src/modules/notifier/CMakeLists.txt | 12 +- src/modules/notifier/NotifierMessage.cpp | 99 + src/modules/notifier/NotifierMessage.h | 87 + src/modules/notifier/NotifierSettings.h | 66 + src/modules/notifier/NotifierWindow.cpp | 1153 ++++++ src/modules/notifier/NotifierWindow.h | 159 + src/modules/notifier/NotifierWindowBorder.cpp | 205 ++ src/modules/notifier/NotifierWindowBorder.h | 130 + src/modules/notifier/NotifierWindowTab.cpp | 230 ++ src/modules/notifier/NotifierWindowTab.h | 120 + src/modules/notifier/libkvinotifier.cpp | 10 +- src/modules/notifier/notifiermessage.cpp | 99 - src/modules/notifier/notifiermessage.h | 87 - src/modules/notifier/notifiersettings.h | 66 - src/modules/notifier/notifierwindow.cpp | 1153 ------ src/modules/notifier/notifierwindow.h | 159 - src/modules/notifier/notifierwindowborder.cpp | 205 -- src/modules/notifier/notifierwindowborder.h | 130 - src/modules/notifier/notifierwindowtab.cpp | 230 -- src/modules/notifier/notifierwindowtab.h | 120 - src/modules/objects/CMakeLists.txt | 148 +- src/modules/objects/KvsObject_button.cpp | 167 + src/modules/objects/KvsObject_button.h | 53 + src/modules/objects/KvsObject_buttonGroup.cpp | 106 + src/modules/objects/KvsObject_buttonGroup.h | 46 + src/modules/objects/KvsObject_checkBox.cpp | 136 + src/modules/objects/KvsObject_checkBox.h | 50 + src/modules/objects/KvsObject_comboBox.cpp | 366 ++ src/modules/objects/KvsObject_comboBox.h | 74 + src/modules/objects/KvsObject_dateTimeEdit.cpp | 162 + src/modules/objects/KvsObject_dateTimeEdit.h | 56 + src/modules/objects/KvsObject_dialog.cpp | 91 + src/modules/objects/KvsObject_dialog.h | 43 + src/modules/objects/KvsObject_dockWindow.cpp | 181 + src/modules/objects/KvsObject_dockWindow.h | 44 + src/modules/objects/KvsObject_file.cpp | 648 ++++ src/modules/objects/KvsObject_file.h | 74 + src/modules/objects/KvsObject_ftp.cpp | 327 ++ src/modules/objects/KvsObject_ftp.h | 64 + src/modules/objects/KvsObject_groupBox.cpp | 335 ++ src/modules/objects/KvsObject_groupBox.h | 63 + src/modules/objects/KvsObject_hBox.cpp | 202 ++ src/modules/objects/KvsObject_hBox.h | 49 + src/modules/objects/KvsObject_http.cpp | 561 +++ src/modules/objects/KvsObject_http.h | 89 + src/modules/objects/KvsObject_label.cpp | 361 ++ src/modules/objects/KvsObject_label.h | 53 + src/modules/objects/KvsObject_layout.cpp | 317 ++ src/modules/objects/KvsObject_layout.h | 53 + src/modules/objects/KvsObject_lcd.cpp | 191 + src/modules/objects/KvsObject_lcd.h | 52 + src/modules/objects/KvsObject_lineEdit.cpp | 543 +++ src/modules/objects/KvsObject_lineEdit.h | 90 + src/modules/objects/KvsObject_list.cpp | 342 ++ src/modules/objects/KvsObject_list.h | 64 + src/modules/objects/KvsObject_listWidget.cpp | 680 ++++ src/modules/objects/KvsObject_listWidget.h | 81 + src/modules/objects/KvsObject_mainWindow.cpp | 101 + src/modules/objects/KvsObject_mainWindow.h | 46 + src/modules/objects/KvsObject_memoryBuffer.cpp | 125 + src/modules/objects/KvsObject_memoryBuffer.h | 53 + src/modules/objects/KvsObject_menuBar.cpp | 77 + src/modules/objects/KvsObject_menuBar.h | 42 + src/modules/objects/KvsObject_multiLineEdit.cpp | 785 +++++ src/modules/objects/KvsObject_multiLineEdit.h | 93 + src/modules/objects/KvsObject_painter.cpp | 1738 +++++++++ src/modules/objects/KvsObject_painter.h | 131 + src/modules/objects/KvsObject_pixmap.cpp | 360 ++ src/modules/objects/KvsObject_pixmap.h | 76 + src/modules/objects/KvsObject_popupMenu.cpp | 398 +++ src/modules/objects/KvsObject_popupMenu.h | 64 + src/modules/objects/KvsObject_process.cpp | 323 ++ src/modules/objects/KvsObject_process.h | 69 + src/modules/objects/KvsObject_progressBar.cpp | 150 + src/modules/objects/KvsObject_progressBar.h | 51 + src/modules/objects/KvsObject_radioButton.cpp | 146 + src/modules/objects/KvsObject_radioButton.h | 51 + src/modules/objects/KvsObject_slider.cpp | 301 ++ src/modules/objects/KvsObject_slider.h | 64 + src/modules/objects/KvsObject_socket.cpp | 1297 +++++++ src/modules/objects/KvsObject_socket.h | 113 + src/modules/objects/KvsObject_spinBox.cpp | 267 ++ src/modules/objects/KvsObject_spinBox.h | 64 + src/modules/objects/KvsObject_sql.cpp | 603 ++++ src/modules/objects/KvsObject_sql.h | 79 + src/modules/objects/KvsObject_tabWidget.cpp | 456 +++ src/modules/objects/KvsObject_tabWidget.h | 67 + src/modules/objects/KvsObject_tableWidget.cpp | 796 +++++ src/modules/objects/KvsObject_tableWidget.h | 116 + src/modules/objects/KvsObject_textBrowser.cpp | 155 + src/modules/objects/KvsObject_textBrowser.h | 53 + src/modules/objects/KvsObject_toolBar.cpp | 128 + src/modules/objects/KvsObject_toolBar.h | 48 + src/modules/objects/KvsObject_toolButton.cpp | 344 ++ src/modules/objects/KvsObject_toolButton.h | 70 + src/modules/objects/KvsObject_trayIcon.cpp | 243 ++ src/modules/objects/KvsObject_trayIcon.h | 58 + src/modules/objects/KvsObject_treeWidget.cpp | 666 ++++ src/modules/objects/KvsObject_treeWidget.h | 100 + src/modules/objects/KvsObject_treeWidgeteItem.cpp | 429 +++ src/modules/objects/KvsObject_treeWidgeteItem.h | 78 + src/modules/objects/KvsObject_vBox.cpp | 209 ++ src/modules/objects/KvsObject_vBox.h | 49 + src/modules/objects/KvsObject_widget.cpp | 2030 +++++++++++ src/modules/objects/KvsObject_widget.h | 145 + src/modules/objects/KvsObject_window.cpp | 158 + src/modules/objects/KvsObject_window.h | 65 + src/modules/objects/KvsObject_wizard.cpp | 386 ++ src/modules/objects/KvsObject_wizard.h | 80 + src/modules/objects/KvsObject_workspace.cpp | 328 ++ src/modules/objects/KvsObject_workspace.h | 57 + src/modules/objects/KvsObject_wrapper.cpp | 221 ++ src/modules/objects/KvsObject_wrapper.h | 51 + src/modules/objects/KvsObject_xmlreader.cpp | 375 ++ src/modules/objects/KvsObject_xmlreader.h | 45 + src/modules/objects/class_button.cpp | 167 - src/modules/objects/class_button.h | 53 - src/modules/objects/class_buttongroup.cpp | 106 - src/modules/objects/class_buttongroup.h | 46 - src/modules/objects/class_checkbox.cpp | 136 - src/modules/objects/class_checkbox.h | 50 - src/modules/objects/class_combobox.cpp | 366 -- src/modules/objects/class_combobox.h | 74 - src/modules/objects/class_datetimeedit.cpp | 162 - src/modules/objects/class_datetimeedit.h | 56 - src/modules/objects/class_dialog.cpp | 91 - src/modules/objects/class_dialog.h | 43 - src/modules/objects/class_dockwindow.cpp | 181 - src/modules/objects/class_dockwindow.h | 44 - src/modules/objects/class_file.cpp | 648 ---- src/modules/objects/class_file.h | 74 - src/modules/objects/class_ftp.cpp | 327 -- src/modules/objects/class_ftp.h | 64 - src/modules/objects/class_groupbox.cpp | 335 -- src/modules/objects/class_groupbox.h | 63 - src/modules/objects/class_hbox.cpp | 202 -- src/modules/objects/class_hbox.h | 49 - src/modules/objects/class_http.cpp | 561 --- src/modules/objects/class_http.h | 89 - src/modules/objects/class_label.cpp | 361 -- src/modules/objects/class_label.h | 53 - src/modules/objects/class_layout.cpp | 317 -- src/modules/objects/class_layout.h | 53 - src/modules/objects/class_lcd.cpp | 191 - src/modules/objects/class_lcd.h | 52 - src/modules/objects/class_lineedit.cpp | 543 --- src/modules/objects/class_lineedit.h | 90 - src/modules/objects/class_list.cpp | 342 -- src/modules/objects/class_list.h | 64 - src/modules/objects/class_listwidget.cpp | 680 ---- src/modules/objects/class_listwidget.h | 81 - src/modules/objects/class_mainwindow.cpp | 101 - src/modules/objects/class_mainwindow.h | 46 - src/modules/objects/class_memorybuffer.cpp | 125 - src/modules/objects/class_memorybuffer.h | 53 - src/modules/objects/class_menubar.cpp | 77 - src/modules/objects/class_menubar.h | 42 - src/modules/objects/class_multilineedit.cpp | 785 ----- src/modules/objects/class_multilineedit.h | 93 - src/modules/objects/class_painter.cpp | 1738 --------- src/modules/objects/class_painter.h | 131 - src/modules/objects/class_pixmap.cpp | 360 -- src/modules/objects/class_pixmap.h | 76 - src/modules/objects/class_popupmenu.cpp | 398 --- src/modules/objects/class_popupmenu.h | 64 - src/modules/objects/class_process.cpp | 323 -- src/modules/objects/class_process.h | 69 - src/modules/objects/class_progressbar.cpp | 150 - src/modules/objects/class_progressbar.h | 51 - src/modules/objects/class_radiobutton.cpp | 146 - src/modules/objects/class_radiobutton.h | 51 - src/modules/objects/class_slider.cpp | 301 -- src/modules/objects/class_slider.h | 64 - src/modules/objects/class_socket.cpp | 1297 ------- src/modules/objects/class_socket.h | 113 - src/modules/objects/class_spinbox.cpp | 267 -- src/modules/objects/class_spinbox.h | 64 - src/modules/objects/class_sql.cpp | 603 ---- src/modules/objects/class_sql.h | 79 - src/modules/objects/class_tablewidget.cpp | 796 ----- src/modules/objects/class_tablewidget.h | 116 - src/modules/objects/class_tabwidget.cpp | 456 --- src/modules/objects/class_tabwidget.h | 67 - src/modules/objects/class_tbrowser.cpp | 155 - src/modules/objects/class_tbrowser.h | 52 - src/modules/objects/class_toolbar.cpp | 128 - src/modules/objects/class_toolbar.h | 48 - src/modules/objects/class_toolbutton.cpp | 344 -- src/modules/objects/class_toolbutton.h | 70 - src/modules/objects/class_trayicon.cpp | 243 -- src/modules/objects/class_trayicon.h | 58 - src/modules/objects/class_treewidget.cpp | 666 ---- src/modules/objects/class_treewidget.h | 100 - src/modules/objects/class_treewidgetitem.cpp | 429 --- src/modules/objects/class_treewidgetitem.h | 78 - src/modules/objects/class_vbox.cpp | 209 -- src/modules/objects/class_vbox.h | 49 - src/modules/objects/class_widget.cpp | 2030 ----------- src/modules/objects/class_widget.h | 145 - src/modules/objects/class_window.cpp | 158 - src/modules/objects/class_window.h | 65 - src/modules/objects/class_wizard.cpp | 386 -- src/modules/objects/class_wizard.h | 80 - src/modules/objects/class_workspace.cpp | 328 -- src/modules/objects/class_workspace.h | 57 - src/modules/objects/class_wrapper.cpp | 221 -- src/modules/objects/class_wrapper.h | 51 - src/modules/objects/class_xmlreader.cpp | 375 -- src/modules/objects/class_xmlreader.h | 45 - src/modules/objects/libkviobjects.cpp | 284 +- src/modules/objects/object_macros.h | 2 +- src/modules/options/CMakeLists.txt | 164 +- src/modules/options/OptionsInstanceManager.cpp | 3695 ++++++++++++++++++++ src/modules/options/OptionsInstanceManager.h | 85 + src/modules/options/OptionsWidgetContainer.cpp | 168 + src/modules/options/OptionsWidgetContainer.h | 58 + .../OptionsWidget_alertsAndHighlighting.cpp | 150 + .../options/OptionsWidget_alertsAndHighlighting.h | 80 + src/modules/options/OptionsWidget_antiSpam.cpp | 66 + src/modules/options/OptionsWidget_antiSpam.h | 49 + src/modules/options/OptionsWidget_avatar.cpp | 121 + src/modules/options/OptionsWidget_avatar.h | 45 + src/modules/options/OptionsWidget_away.cpp | 74 + src/modules/options/OptionsWidget_away.h | 50 + src/modules/options/OptionsWidget_channel.cpp | 166 + src/modules/options/OptionsWidget_channel.h | 79 + src/modules/options/OptionsWidget_connection.cpp | 304 ++ src/modules/options/OptionsWidget_connection.h | 117 + src/modules/options/OptionsWidget_ctcp.cpp | 83 + src/modules/options/OptionsWidget_ctcp.h | 43 + .../options/OptionsWidget_ctcpFloodProtection.cpp | 118 + .../options/OptionsWidget_ctcpFloodProtection.h | 42 + src/modules/options/OptionsWidget_dcc.cpp | 372 ++ src/modules/options/OptionsWidget_dcc.h | 141 + src/modules/options/OptionsWidget_general.cpp | 51 + src/modules/options/OptionsWidget_general.h | 41 + src/modules/options/OptionsWidget_identity.cpp | 1017 ++++++ src/modules/options/OptionsWidget_identity.h | 255 ++ src/modules/options/OptionsWidget_ignore.cpp | 66 + src/modules/options/OptionsWidget_ignore.h | 50 + src/modules/options/OptionsWidget_input.cpp | 167 + src/modules/options/OptionsWidget_input.h | 62 + .../options/OptionsWidget_interfaceFeatures.cpp | 91 + .../options/OptionsWidget_interfaceFeatures.h | 47 + src/modules/options/OptionsWidget_irc.cpp | 88 + src/modules/options/OptionsWidget_irc.h | 69 + src/modules/options/OptionsWidget_ircOutput.cpp | 111 + src/modules/options/OptionsWidget_ircOutput.h | 51 + src/modules/options/OptionsWidget_ircView.cpp | 221 ++ src/modules/options/OptionsWidget_ircView.h | 101 + src/modules/options/OptionsWidget_lag.cpp | 80 + src/modules/options/OptionsWidget_lag.h | 43 + src/modules/options/OptionsWidget_logging.cpp | 70 + src/modules/options/OptionsWidget_logging.h | 44 + src/modules/options/OptionsWidget_mediaTypes.cpp | 265 ++ src/modules/options/OptionsWidget_mediaTypes.h | 85 + src/modules/options/OptionsWidget_message.cpp | 656 ++++ src/modules/options/OptionsWidget_message.h | 205 ++ src/modules/options/OptionsWidget_nickserv.cpp | 371 ++ src/modules/options/OptionsWidget_nickserv.h | 89 + src/modules/options/OptionsWidget_notifier.cpp | 262 ++ src/modules/options/OptionsWidget_notifier.h | 63 + src/modules/options/OptionsWidget_notify.cpp | 107 + src/modules/options/OptionsWidget_notify.h | 43 + src/modules/options/OptionsWidget_protection.cpp | 47 + src/modules/options/OptionsWidget_protection.h | 47 + src/modules/options/OptionsWidget_proxy.cpp | 364 ++ src/modules/options/OptionsWidget_proxy.h | 95 + src/modules/options/OptionsWidget_query.cpp | 116 + src/modules/options/OptionsWidget_query.h | 44 + src/modules/options/OptionsWidget_servers.cpp | 2001 +++++++++++ src/modules/options/OptionsWidget_servers.h | 229 ++ src/modules/options/OptionsWidget_sound.cpp | 356 ++ src/modules/options/OptionsWidget_sound.h | 97 + src/modules/options/OptionsWidget_textEncoding.cpp | 169 + src/modules/options/OptionsWidget_textEncoding.h | 52 + src/modules/options/OptionsWidget_textIcons.cpp | 291 ++ src/modules/options/OptionsWidget_textIcons.h | 90 + src/modules/options/OptionsWidget_theme.cpp | 204 ++ src/modules/options/OptionsWidget_theme.h | 100 + src/modules/options/OptionsWidget_tools.cpp | 51 + src/modules/options/OptionsWidget_tools.h | 46 + src/modules/options/OptionsWidget_topicLabel.cpp | 50 + src/modules/options/OptionsWidget_topicLabel.h | 44 + src/modules/options/OptionsWidget_tray.cpp | 101 + src/modules/options/OptionsWidget_tray.h | 52 + src/modules/options/OptionsWidget_uparser.cpp | 64 + src/modules/options/OptionsWidget_uparser.h | 42 + src/modules/options/OptionsWidget_urlHandlers.cpp | 154 + src/modules/options/OptionsWidget_urlHandlers.h | 59 + src/modules/options/OptionsWidget_userList.cpp | 250 ++ src/modules/options/OptionsWidget_userList.h | 116 + src/modules/options/OptionsWidget_windowList.cpp | 269 ++ src/modules/options/OptionsWidget_windowList.h | 126 + src/modules/options/container.cpp | 168 - src/modules/options/container.h | 58 - src/modules/options/dialog.cpp | 94 +- src/modules/options/dialog.h | 36 +- src/modules/options/instances.cpp | 3695 -------------------- src/modules/options/instances.h | 85 - src/modules/options/libkvioptions.cpp | 36 +- src/modules/options/mkcreateinstanceproc.sh | 112 +- src/modules/options/optw_antispam.cpp | 66 - src/modules/options/optw_antispam.h | 49 - src/modules/options/optw_avatar.cpp | 121 - src/modules/options/optw_avatar.h | 45 - src/modules/options/optw_away.cpp | 74 - src/modules/options/optw_away.h | 50 - src/modules/options/optw_channel.cpp | 166 - src/modules/options/optw_channel.h | 79 - src/modules/options/optw_connection.cpp | 304 -- src/modules/options/optw_connection.h | 117 - src/modules/options/optw_ctcp.cpp | 83 - src/modules/options/optw_ctcp.h | 43 - src/modules/options/optw_ctcpfloodprotection.cpp | 118 - src/modules/options/optw_ctcpfloodprotection.h | 42 - src/modules/options/optw_dcc.cpp | 372 -- src/modules/options/optw_dcc.h | 141 - src/modules/options/optw_generalopt.cpp | 51 - src/modules/options/optw_generalopt.h | 41 - src/modules/options/optw_highlighting.cpp | 150 - src/modules/options/optw_highlighting.h | 80 - src/modules/options/optw_identity.cpp | 1017 ------ src/modules/options/optw_identity.h | 255 -- src/modules/options/optw_ignore.cpp | 66 - src/modules/options/optw_ignore.h | 50 - src/modules/options/optw_input.cpp | 167 - src/modules/options/optw_input.h | 62 - src/modules/options/optw_interfacefeatures.cpp | 91 - src/modules/options/optw_interfacefeatures.h | 47 - src/modules/options/optw_interfacelookglobal.cpp | 204 -- src/modules/options/optw_interfacelookglobal.h | 100 - src/modules/options/optw_irc.cpp | 88 - src/modules/options/optw_irc.h | 69 - src/modules/options/optw_ircoutput.cpp | 111 - src/modules/options/optw_ircoutput.h | 51 - src/modules/options/optw_ircview.cpp | 221 -- src/modules/options/optw_ircview.h | 101 - src/modules/options/optw_lag.cpp | 80 - src/modules/options/optw_lag.h | 43 - src/modules/options/optw_logging.cpp | 70 - src/modules/options/optw_logging.h | 44 - src/modules/options/optw_mediatypes.cpp | 265 -- src/modules/options/optw_mediatypes.h | 85 - src/modules/options/optw_messages.cpp | 656 ---- src/modules/options/optw_messages.h | 205 -- src/modules/options/optw_nickserv.cpp | 371 -- src/modules/options/optw_nickserv.h | 89 - src/modules/options/optw_notifier.cpp | 262 -- src/modules/options/optw_notifier.h | 63 - src/modules/options/optw_notify.cpp | 107 - src/modules/options/optw_notify.h | 43 - src/modules/options/optw_protection.cpp | 47 - src/modules/options/optw_protection.h | 47 - src/modules/options/optw_proxy.cpp | 364 -- src/modules/options/optw_proxy.h | 95 - src/modules/options/optw_query.cpp | 116 - src/modules/options/optw_query.h | 44 - src/modules/options/optw_servers.cpp | 2001 ----------- src/modules/options/optw_servers.h | 229 -- src/modules/options/optw_sound.cpp | 356 -- src/modules/options/optw_sound.h | 97 - src/modules/options/optw_textencoding.cpp | 169 - src/modules/options/optw_textencoding.h | 52 - src/modules/options/optw_texticons.cpp | 291 -- src/modules/options/optw_texticons.h | 90 - src/modules/options/optw_tools.cpp | 51 - src/modules/options/optw_tools.h | 46 - src/modules/options/optw_topiclabel.cpp | 50 - src/modules/options/optw_topiclabel.h | 44 - src/modules/options/optw_tray.cpp | 101 - src/modules/options/optw_tray.h | 52 - src/modules/options/optw_uparser.cpp | 64 - src/modules/options/optw_uparser.h | 42 - src/modules/options/optw_urlhandlers.cpp | 154 - src/modules/options/optw_urlhandlers.h | 59 - src/modules/options/optw_userlist.cpp | 250 -- src/modules/options/optw_userlist.h | 116 - src/modules/options/optw_windowlist.cpp | 269 -- src/modules/options/optw_windowlist.h | 126 - src/modules/popupeditor/CMakeLists.txt | 4 +- src/modules/popupeditor/PopupEditorWindow.cpp | 1460 ++++++++ src/modules/popupeditor/PopupEditorWindow.h | 205 ++ src/modules/popupeditor/libkvipopupeditor.cpp | 6 +- src/modules/popupeditor/popupeditor.cpp | 1460 -------- src/modules/popupeditor/popupeditor.h | 205 -- src/modules/raweditor/CMakeLists.txt | 4 +- src/modules/raweditor/RawEditorWindow.cpp | 558 +++ src/modules/raweditor/RawEditorWindow.h | 141 + src/modules/raweditor/libkviraweditor.cpp | 6 +- src/modules/raweditor/raweditor.cpp | 558 --- src/modules/raweditor/raweditor.h | 141 - src/modules/reguser/CMakeLists.txt | 8 +- src/modules/reguser/RegisteredUserEntryDialog.cpp | 798 +++++ src/modules/reguser/RegisteredUserEntryDialog.h | 140 + src/modules/reguser/RegistrationWizard.cpp | 478 +++ src/modules/reguser/RegistrationWizard.h | 91 + src/modules/reguser/dialog.cpp | 158 +- src/modules/reguser/dialog.h | 44 +- src/modules/reguser/edituser.cpp | 798 ----- src/modules/reguser/edituser.h | 140 - src/modules/reguser/libkvireguser.cpp | 18 +- src/modules/reguser/wizard.cpp | 478 --- src/modules/reguser/wizard.h | 91 - src/modules/rijndael/BlowFish.cpp | 634 ++++ src/modules/rijndael/BlowFish.h | 141 + src/modules/rijndael/CMakeLists.txt | 4 +- src/modules/rijndael/Rijndael.cpp | 1628 +++++++++ src/modules/rijndael/Rijndael.h | 155 + src/modules/rijndael/ablowfish.cpp | 634 ---- src/modules/rijndael/ablowfish.h | 141 - src/modules/rijndael/libkvirijndael.cpp | 4 +- src/modules/rijndael/libkvirijndael.h | 2 +- src/modules/rijndael/rijndael.cpp | 1628 --------- src/modules/rijndael/rijndael.h | 155 - src/modules/setup/CMakeLists.txt | 4 +- src/modules/setup/SetupWizard.cpp | 1146 ++++++ src/modules/setup/SetupWizard.h | 158 + src/modules/setup/libkvisetup.cpp | 4 +- src/modules/setup/setupwizard.cpp | 1146 ------ src/modules/setup/setupwizard.h | 158 - src/modules/sharedfileswindow/CMakeLists.txt | 4 +- .../sharedfileswindow/SharedFilesWindow.cpp | 738 ++++ src/modules/sharedfileswindow/SharedFilesWindow.h | 111 + .../sharedfileswindow/libkvisharedfileswindow.cpp | 6 +- .../sharedfileswindow/sharedfileswindow.cpp | 738 ---- src/modules/sharedfileswindow/sharedfileswindow.h | 111 - src/modules/socketspy/libkvisocketspy.cpp | 6 +- src/modules/socketspy/socketspywindow.cpp | 28 +- src/modules/socketspy/socketspywindow.h | 6 +- src/modules/spaste/CMakeLists.txt | 4 +- src/modules/spaste/SlowPasteController.cpp | 139 + src/modules/spaste/SlowPasteController.h | 60 + src/modules/spaste/controller.cpp | 139 - src/modules/spaste/controller.h | 60 - src/modules/spaste/libkvispaste.cpp | 26 +- src/modules/system/CMakeLists.txt | 2 +- src/modules/system/Plugin.cpp | 420 +++ src/modules/system/Plugin.h | 82 + src/modules/system/libkvisystem.cpp | 6 +- src/modules/system/plugin.cpp | 420 --- src/modules/system/plugin.h | 82 - src/modules/term/CMakeLists.txt | 8 +- src/modules/term/TermWidget.cpp | 178 + src/modules/term/TermWidget.h | 70 + src/modules/term/TermWindow.cpp | 80 + src/modules/term/TermWindow.h | 52 + src/modules/term/libkviterm.cpp | 16 +- src/modules/term/termwidget.cpp | 178 - src/modules/term/termwidget.h | 70 - src/modules/term/termwindow.cpp | 80 - src/modules/term/termwindow.h | 52 - src/modules/theme/CMakeLists.txt | 10 +- src/modules/theme/PackThemeDialog.cpp | 576 +++ src/modules/theme/PackThemeDialog.h | 124 + src/modules/theme/SaveThemeDialog.cpp | 306 ++ src/modules/theme/SaveThemeDialog.h | 66 + src/modules/theme/ThemeFunctions.cpp | 405 +++ src/modules/theme/ThemeFunctions.h | 57 + src/modules/theme/libkvitheme.cpp | 12 +- src/modules/theme/managementdialog.cpp | 76 +- src/modules/theme/managementdialog.h | 16 +- src/modules/theme/packthemedialog.cpp | 576 --- src/modules/theme/packthemedialog.h | 124 - src/modules/theme/savethemedialog.cpp | 306 -- src/modules/theme/savethemedialog.h | 66 - src/modules/theme/themefunctions.cpp | 405 --- src/modules/theme/themefunctions.h | 57 - src/modules/tip/libkvitip.cpp | 28 +- src/modules/tip/libkvitip.h | 14 +- src/modules/toolbareditor/CMakeLists.txt | 4 +- .../toolbareditor/CustomizeToolBarsDialog.cpp | 567 +++ .../toolbareditor/CustomizeToolBarsDialog.h | 123 + src/modules/toolbareditor/libkvitoolbareditor.cpp | 8 +- src/modules/toolbareditor/toolbareditor.cpp | 567 --- src/modules/toolbareditor/toolbareditor.h | 123 - src/modules/torrent/CMakeLists.txt | 10 +- src/modules/torrent/KTorrentDbusInterface.cpp | 505 +++ src/modules/torrent/KTorrentDbusInterface.h | 120 + src/modules/torrent/StatusBarApplet.cpp | 98 + src/modules/torrent/StatusBarApplet.h | 45 + src/modules/torrent/TorrentInterface.cpp | 31 + src/modules/torrent/TorrentInterface.h | 159 + src/modules/torrent/libkvitorrent.cpp | 68 +- src/modules/torrent/tc_interface.cpp | 31 - src/modules/torrent/tc_interface.h | 159 - src/modules/torrent/tc_ktorrentdbusinterface.cpp | 505 --- src/modules/torrent/tc_ktorrentdbusinterface.h | 120 - src/modules/torrent/tc_statusbarapplet.cpp | 98 - src/modules/torrent/tc_statusbarapplet.h | 45 - src/modules/trayicon/libkvitrayicon.cpp | 44 +- src/modules/trayicon/libkvitrayicon.h | 6 +- src/modules/upnp/CMakeLists.txt | 18 +- src/modules/upnp/Manager.cpp | 175 + src/modules/upnp/Manager.h | 116 + src/modules/upnp/RootService.cpp | 316 ++ src/modules/upnp/RootService.h | 103 + src/modules/upnp/Service.cpp | 331 ++ src/modules/upnp/Service.h | 137 + src/modules/upnp/SsdpConnection.cpp | 152 + src/modules/upnp/SsdpConnection.h | 79 + src/modules/upnp/WanConnectionService.cpp | 199 ++ src/modules/upnp/WanConnectionService.h | 114 + src/modules/upnp/XmlFunctions.cpp | 127 + src/modules/upnp/XmlFunctions.h | 62 + src/modules/upnp/igdcontrolpoint.cpp | 4 +- src/modules/upnp/libkviupnp.cpp | 2 +- src/modules/upnp/manager.cpp | 175 - src/modules/upnp/manager.h | 116 - src/modules/upnp/rootservice.cpp | 316 -- src/modules/upnp/rootservice.h | 103 - src/modules/upnp/service.cpp | 331 -- src/modules/upnp/service.h | 137 - src/modules/upnp/ssdpconnection.cpp | 152 - src/modules/upnp/ssdpconnection.h | 79 - src/modules/upnp/wanconnectionservice.cpp | 199 -- src/modules/upnp/wanconnectionservice.h | 114 - src/modules/upnp/xmlfunctions.cpp | 127 - src/modules/upnp/xmlfunctions.h | 62 - src/modules/url/libkviurl.cpp | 8 +- src/modules/url/libkviurl.h | 8 +- src/modules/window/CMakeLists.txt | 4 +- src/modules/window/UserWindow.cpp | 101 + src/modules/window/UserWindow.h | 48 + src/modules/window/libkviwindow.cpp | 14 +- src/modules/window/userwindow.cpp | 101 - src/modules/window/userwindow.h | 48 - 738 files changed, 86976 insertions(+), 86975 deletions(-) create mode 100644 src/modules/about/AboutDialog.cpp create mode 100644 src/modules/about/AboutDialog.h delete mode 100644 src/modules/about/aboutdialog.cpp delete mode 100644 src/modules/about/aboutdialog.h create mode 100644 src/modules/actioneditor/ActionEditor.cpp create mode 100644 src/modules/actioneditor/ActionEditor.h delete mode 100644 src/modules/actioneditor/actioneditor.cpp delete mode 100644 src/modules/actioneditor/actioneditor.h create mode 100644 src/modules/addon/AddonFunctions.cpp create mode 100644 src/modules/addon/AddonFunctions.h create mode 100644 src/modules/addon/PackAddonDialog.cpp create mode 100644 src/modules/addon/PackAddonDialog.h delete mode 100644 src/modules/addon/addonfunctions.cpp delete mode 100644 src/modules/addon/addonfunctions.h delete mode 100644 src/modules/addon/packaddondialog.cpp delete mode 100644 src/modules/addon/packaddondialog.h create mode 100644 src/modules/aliaseditor/AliasEditorWindow.cpp create mode 100644 src/modules/aliaseditor/AliasEditorWindow.h delete mode 100644 src/modules/aliaseditor/aliaseditor.cpp delete mode 100644 src/modules/aliaseditor/aliaseditor.h create mode 100644 src/modules/channelsjoin/ChannelsJoinDialog.cpp create mode 100644 src/modules/channelsjoin/ChannelsJoinDialog.h delete mode 100644 src/modules/channelsjoin/channelsjoinwindow.cpp delete mode 100644 src/modules/channelsjoin/channelsjoinwindow.h create mode 100644 src/modules/classeditor/ClassEditorWindow.cpp create mode 100644 src/modules/classeditor/ClassEditorWindow.h delete mode 100644 src/modules/classeditor/classeditor.cpp delete mode 100644 src/modules/classeditor/classeditor.h create mode 100644 src/modules/codetester/CodeTesterWindow.cpp create mode 100644 src/modules/codetester/CodeTesterWindow.h delete mode 100644 src/modules/codetester/codetester.cpp delete mode 100644 src/modules/codetester/codetester.h create mode 100644 src/modules/dcc/DccBroker.cpp create mode 100644 src/modules/dcc/DccBroker.h create mode 100644 src/modules/dcc/DccCanvasWindow.cpp create mode 100644 src/modules/dcc/DccCanvasWindow.h create mode 100644 src/modules/dcc/DccChatWindow.cpp create mode 100644 src/modules/dcc/DccChatWindow.h create mode 100644 src/modules/dcc/DccDescriptor.cpp create mode 100644 src/modules/dcc/DccDescriptor.h create mode 100644 src/modules/dcc/DccDialog.cpp create mode 100644 src/modules/dcc/DccDialog.h create mode 100644 src/modules/dcc/DccFileTransfer.cpp create mode 100644 src/modules/dcc/DccFileTransfer.h create mode 100644 src/modules/dcc/DccMarshal.cpp create mode 100644 src/modules/dcc/DccMarshal.h create mode 100644 src/modules/dcc/DccThread.cpp create mode 100644 src/modules/dcc/DccThread.h create mode 100644 src/modules/dcc/DccUtils.cpp create mode 100644 src/modules/dcc/DccUtils.h create mode 100644 src/modules/dcc/DccVideoWindow.cpp create mode 100644 src/modules/dcc/DccVideoWindow.h create mode 100644 src/modules/dcc/DccVoiceAdpcmCodec.cpp create mode 100644 src/modules/dcc/DccVoiceAdpcmCodec.h create mode 100644 src/modules/dcc/DccVoiceCodec.cpp create mode 100644 src/modules/dcc/DccVoiceCodec.h create mode 100644 src/modules/dcc/DccVoiceGsmCodec.cpp create mode 100644 src/modules/dcc/DccVoiceGsmCodec.h create mode 100644 src/modules/dcc/DccVoiceWindow.cpp create mode 100644 src/modules/dcc/DccVoiceWindow.h create mode 100644 src/modules/dcc/DccWindow.cpp create mode 100644 src/modules/dcc/DccWindow.h delete mode 100644 src/modules/dcc/adpcmcodec.cpp delete mode 100644 src/modules/dcc/adpcmcodec.h delete mode 100644 src/modules/dcc/broker.cpp delete mode 100644 src/modules/dcc/broker.h delete mode 100644 src/modules/dcc/canvas.cpp delete mode 100644 src/modules/dcc/canvas.h delete mode 100644 src/modules/dcc/chat.cpp delete mode 100644 src/modules/dcc/chat.h delete mode 100644 src/modules/dcc/codec.cpp delete mode 100644 src/modules/dcc/codec.h delete mode 100644 src/modules/dcc/descriptor.cpp delete mode 100644 src/modules/dcc/descriptor.h delete mode 100644 src/modules/dcc/dialogs.cpp delete mode 100644 src/modules/dcc/dialogs.h delete mode 100644 src/modules/dcc/gsmcodec.cpp delete mode 100644 src/modules/dcc/gsmcodec.h delete mode 100644 src/modules/dcc/marshal.cpp delete mode 100644 src/modules/dcc/marshal.h delete mode 100644 src/modules/dcc/send.cpp delete mode 100644 src/modules/dcc/send.h delete mode 100644 src/modules/dcc/thread.cpp delete mode 100644 src/modules/dcc/thread.h delete mode 100644 src/modules/dcc/utils.cpp delete mode 100644 src/modules/dcc/utils.h delete mode 100644 src/modules/dcc/video.cpp delete mode 100644 src/modules/dcc/video.h delete mode 100644 src/modules/dcc/voice.cpp delete mode 100644 src/modules/dcc/voice.h delete mode 100644 src/modules/dcc/window.cpp delete mode 100644 src/modules/dcc/window.h create mode 100644 src/modules/editor/ScriptEditorImplementation.cpp create mode 100644 src/modules/editor/ScriptEditorImplementation.h delete mode 100644 src/modules/editor/scripteditor.cpp delete mode 100644 src/modules/editor/scripteditor.h create mode 100644 src/modules/eventeditor/EventEditorWindow.cpp create mode 100644 src/modules/eventeditor/EventEditorWindow.h delete mode 100644 src/modules/eventeditor/eventeditor.cpp delete mode 100644 src/modules/eventeditor/eventeditor.h create mode 100644 src/modules/filetransferwindow/FileTransferWindow.cpp create mode 100644 src/modules/filetransferwindow/FileTransferWindow.h delete mode 100644 src/modules/filetransferwindow/filetransferwindow.cpp delete mode 100644 src/modules/filetransferwindow/filetransferwindow.h create mode 100644 src/modules/help/HelpIndex.cpp create mode 100644 src/modules/help/HelpIndex.h create mode 100644 src/modules/help/HelpWidget.cpp create mode 100644 src/modules/help/HelpWidget.h create mode 100644 src/modules/help/HelpWindow.cpp create mode 100644 src/modules/help/HelpWindow.h delete mode 100644 src/modules/help/helpwidget.cpp delete mode 100644 src/modules/help/helpwidget.h delete mode 100644 src/modules/help/helpwindow.cpp delete mode 100644 src/modules/help/helpwindow.h delete mode 100644 src/modules/help/index.cpp delete mode 100644 src/modules/help/index.h create mode 100644 src/modules/http/HttpFileTransfer.cpp create mode 100644 src/modules/http/HttpFileTransfer.h delete mode 100644 src/modules/http/httpfiletransfer.cpp delete mode 100644 src/modules/http/httpfiletransfer.h create mode 100644 src/modules/links/LinksWindow.cpp create mode 100644 src/modules/links/LinksWindow.h delete mode 100644 src/modules/links/linkswindow.cpp delete mode 100644 src/modules/links/linkswindow.h create mode 100644 src/modules/list/ListWindow.cpp create mode 100644 src/modules/list/ListWindow.h delete mode 100644 src/modules/list/listwindow.cpp delete mode 100644 src/modules/list/listwindow.h create mode 100644 src/modules/logview/LogViewWidget.cpp create mode 100644 src/modules/logview/LogViewWidget.h create mode 100644 src/modules/logview/LogViewWindow.cpp create mode 100644 src/modules/logview/LogViewWindow.h delete mode 100644 src/modules/logview/logviewmdiwindow.cpp delete mode 100644 src/modules/logview/logviewmdiwindow.h delete mode 100644 src/modules/logview/logviewwidget.cpp delete mode 100644 src/modules/logview/logviewwidget.h create mode 100644 src/modules/mediaplayer/MpAmipInterface.cpp create mode 100644 src/modules/mediaplayer/MpAmipInterface.h create mode 100644 src/modules/mediaplayer/MpInterface.cpp create mode 100644 src/modules/mediaplayer/MpInterface.h create mode 100644 src/modules/mediaplayer/MpMp3.cpp create mode 100644 src/modules/mediaplayer/MpMp3.h create mode 100644 src/modules/mediaplayer/MpMprisInterface.cpp create mode 100644 src/modules/mediaplayer/MpMprisInterface.h create mode 100644 src/modules/mediaplayer/MpWinampInterface.cpp create mode 100644 src/modules/mediaplayer/MpWinampInterface.h create mode 100644 src/modules/mediaplayer/MpXmmsInterface.cpp create mode 100644 src/modules/mediaplayer/MpXmmsInterface.h delete mode 100644 src/modules/mediaplayer/mp_amipinterface.cpp delete mode 100644 src/modules/mediaplayer/mp_amipinterface.h delete mode 100644 src/modules/mediaplayer/mp_interface.cpp delete mode 100644 src/modules/mediaplayer/mp_interface.h delete mode 100644 src/modules/mediaplayer/mp_mp3.cpp delete mode 100644 src/modules/mediaplayer/mp_mp3.h delete mode 100644 src/modules/mediaplayer/mp_mprisinterface.cpp delete mode 100644 src/modules/mediaplayer/mp_mprisinterface.h delete mode 100644 src/modules/mediaplayer/mp_winampinterface.cpp delete mode 100644 src/modules/mediaplayer/mp_winampinterface.h delete mode 100644 src/modules/mediaplayer/mp_xmmsinterface.cpp delete mode 100644 src/modules/mediaplayer/mp_xmmsinterface.h create mode 100644 src/modules/my/Idle.cpp create mode 100644 src/modules/my/Idle.h create mode 100644 src/modules/my/Idle_mac.cpp create mode 100644 src/modules/my/Idle_win.cpp create mode 100644 src/modules/my/Idle_x11.cpp delete mode 100644 src/modules/my/idle.cpp delete mode 100644 src/modules/my/idle.h delete mode 100644 src/modules/my/idle_mac.cpp delete mode 100644 src/modules/my/idle_win.cpp delete mode 100644 src/modules/my/idle_x11.cpp create mode 100644 src/modules/notifier/NotifierMessage.cpp create mode 100644 src/modules/notifier/NotifierMessage.h create mode 100644 src/modules/notifier/NotifierSettings.h create mode 100644 src/modules/notifier/NotifierWindow.cpp create mode 100644 src/modules/notifier/NotifierWindow.h create mode 100644 src/modules/notifier/NotifierWindowBorder.cpp create mode 100644 src/modules/notifier/NotifierWindowBorder.h create mode 100644 src/modules/notifier/NotifierWindowTab.cpp create mode 100644 src/modules/notifier/NotifierWindowTab.h delete mode 100644 src/modules/notifier/notifiermessage.cpp delete mode 100644 src/modules/notifier/notifiermessage.h delete mode 100644 src/modules/notifier/notifiersettings.h delete mode 100644 src/modules/notifier/notifierwindow.cpp delete mode 100644 src/modules/notifier/notifierwindow.h delete mode 100644 src/modules/notifier/notifierwindowborder.cpp delete mode 100644 src/modules/notifier/notifierwindowborder.h delete mode 100644 src/modules/notifier/notifierwindowtab.cpp delete mode 100644 src/modules/notifier/notifierwindowtab.h create mode 100644 src/modules/objects/KvsObject_button.cpp create mode 100644 src/modules/objects/KvsObject_button.h create mode 100644 src/modules/objects/KvsObject_buttonGroup.cpp create mode 100644 src/modules/objects/KvsObject_buttonGroup.h create mode 100644 src/modules/objects/KvsObject_checkBox.cpp create mode 100644 src/modules/objects/KvsObject_checkBox.h create mode 100644 src/modules/objects/KvsObject_comboBox.cpp create mode 100644 src/modules/objects/KvsObject_comboBox.h create mode 100644 src/modules/objects/KvsObject_dateTimeEdit.cpp create mode 100644 src/modules/objects/KvsObject_dateTimeEdit.h create mode 100644 src/modules/objects/KvsObject_dialog.cpp create mode 100644 src/modules/objects/KvsObject_dialog.h create mode 100644 src/modules/objects/KvsObject_dockWindow.cpp create mode 100644 src/modules/objects/KvsObject_dockWindow.h create mode 100644 src/modules/objects/KvsObject_file.cpp create mode 100644 src/modules/objects/KvsObject_file.h create mode 100644 src/modules/objects/KvsObject_ftp.cpp create mode 100644 src/modules/objects/KvsObject_ftp.h create mode 100644 src/modules/objects/KvsObject_groupBox.cpp create mode 100644 src/modules/objects/KvsObject_groupBox.h create mode 100644 src/modules/objects/KvsObject_hBox.cpp create mode 100644 src/modules/objects/KvsObject_hBox.h create mode 100644 src/modules/objects/KvsObject_http.cpp create mode 100644 src/modules/objects/KvsObject_http.h create mode 100644 src/modules/objects/KvsObject_label.cpp create mode 100644 src/modules/objects/KvsObject_label.h create mode 100644 src/modules/objects/KvsObject_layout.cpp create mode 100644 src/modules/objects/KvsObject_layout.h create mode 100644 src/modules/objects/KvsObject_lcd.cpp create mode 100644 src/modules/objects/KvsObject_lcd.h create mode 100644 src/modules/objects/KvsObject_lineEdit.cpp create mode 100644 src/modules/objects/KvsObject_lineEdit.h create mode 100644 src/modules/objects/KvsObject_list.cpp create mode 100644 src/modules/objects/KvsObject_list.h create mode 100644 src/modules/objects/KvsObject_listWidget.cpp create mode 100644 src/modules/objects/KvsObject_listWidget.h create mode 100644 src/modules/objects/KvsObject_mainWindow.cpp create mode 100644 src/modules/objects/KvsObject_mainWindow.h create mode 100644 src/modules/objects/KvsObject_memoryBuffer.cpp create mode 100644 src/modules/objects/KvsObject_memoryBuffer.h create mode 100644 src/modules/objects/KvsObject_menuBar.cpp create mode 100644 src/modules/objects/KvsObject_menuBar.h create mode 100644 src/modules/objects/KvsObject_multiLineEdit.cpp create mode 100644 src/modules/objects/KvsObject_multiLineEdit.h create mode 100644 src/modules/objects/KvsObject_painter.cpp create mode 100644 src/modules/objects/KvsObject_painter.h create mode 100644 src/modules/objects/KvsObject_pixmap.cpp create mode 100644 src/modules/objects/KvsObject_pixmap.h create mode 100644 src/modules/objects/KvsObject_popupMenu.cpp create mode 100644 src/modules/objects/KvsObject_popupMenu.h create mode 100644 src/modules/objects/KvsObject_process.cpp create mode 100644 src/modules/objects/KvsObject_process.h create mode 100644 src/modules/objects/KvsObject_progressBar.cpp create mode 100644 src/modules/objects/KvsObject_progressBar.h create mode 100644 src/modules/objects/KvsObject_radioButton.cpp create mode 100644 src/modules/objects/KvsObject_radioButton.h create mode 100644 src/modules/objects/KvsObject_slider.cpp create mode 100644 src/modules/objects/KvsObject_slider.h create mode 100644 src/modules/objects/KvsObject_socket.cpp create mode 100644 src/modules/objects/KvsObject_socket.h create mode 100644 src/modules/objects/KvsObject_spinBox.cpp create mode 100644 src/modules/objects/KvsObject_spinBox.h create mode 100644 src/modules/objects/KvsObject_sql.cpp create mode 100644 src/modules/objects/KvsObject_sql.h create mode 100644 src/modules/objects/KvsObject_tabWidget.cpp create mode 100644 src/modules/objects/KvsObject_tabWidget.h create mode 100644 src/modules/objects/KvsObject_tableWidget.cpp create mode 100644 src/modules/objects/KvsObject_tableWidget.h create mode 100644 src/modules/objects/KvsObject_textBrowser.cpp create mode 100644 src/modules/objects/KvsObject_textBrowser.h create mode 100644 src/modules/objects/KvsObject_toolBar.cpp create mode 100644 src/modules/objects/KvsObject_toolBar.h create mode 100644 src/modules/objects/KvsObject_toolButton.cpp create mode 100644 src/modules/objects/KvsObject_toolButton.h create mode 100644 src/modules/objects/KvsObject_trayIcon.cpp create mode 100644 src/modules/objects/KvsObject_trayIcon.h create mode 100644 src/modules/objects/KvsObject_treeWidget.cpp create mode 100644 src/modules/objects/KvsObject_treeWidget.h create mode 100644 src/modules/objects/KvsObject_treeWidgeteItem.cpp create mode 100644 src/modules/objects/KvsObject_treeWidgeteItem.h create mode 100644 src/modules/objects/KvsObject_vBox.cpp create mode 100644 src/modules/objects/KvsObject_vBox.h create mode 100644 src/modules/objects/KvsObject_widget.cpp create mode 100644 src/modules/objects/KvsObject_widget.h create mode 100644 src/modules/objects/KvsObject_window.cpp create mode 100644 src/modules/objects/KvsObject_window.h create mode 100644 src/modules/objects/KvsObject_wizard.cpp create mode 100644 src/modules/objects/KvsObject_wizard.h create mode 100644 src/modules/objects/KvsObject_workspace.cpp create mode 100644 src/modules/objects/KvsObject_workspace.h create mode 100644 src/modules/objects/KvsObject_wrapper.cpp create mode 100644 src/modules/objects/KvsObject_wrapper.h create mode 100644 src/modules/objects/KvsObject_xmlreader.cpp create mode 100644 src/modules/objects/KvsObject_xmlreader.h delete mode 100644 src/modules/objects/class_button.cpp delete mode 100644 src/modules/objects/class_button.h delete mode 100644 src/modules/objects/class_buttongroup.cpp delete mode 100644 src/modules/objects/class_buttongroup.h delete mode 100644 src/modules/objects/class_checkbox.cpp delete mode 100644 src/modules/objects/class_checkbox.h delete mode 100644 src/modules/objects/class_combobox.cpp delete mode 100644 src/modules/objects/class_combobox.h delete mode 100644 src/modules/objects/class_datetimeedit.cpp delete mode 100644 src/modules/objects/class_datetimeedit.h delete mode 100644 src/modules/objects/class_dialog.cpp delete mode 100644 src/modules/objects/class_dialog.h delete mode 100644 src/modules/objects/class_dockwindow.cpp delete mode 100644 src/modules/objects/class_dockwindow.h delete mode 100644 src/modules/objects/class_file.cpp delete mode 100644 src/modules/objects/class_file.h delete mode 100644 src/modules/objects/class_ftp.cpp delete mode 100644 src/modules/objects/class_ftp.h delete mode 100644 src/modules/objects/class_groupbox.cpp delete mode 100644 src/modules/objects/class_groupbox.h delete mode 100644 src/modules/objects/class_hbox.cpp delete mode 100644 src/modules/objects/class_hbox.h delete mode 100644 src/modules/objects/class_http.cpp delete mode 100644 src/modules/objects/class_http.h delete mode 100644 src/modules/objects/class_label.cpp delete mode 100644 src/modules/objects/class_label.h delete mode 100644 src/modules/objects/class_layout.cpp delete mode 100644 src/modules/objects/class_layout.h delete mode 100644 src/modules/objects/class_lcd.cpp delete mode 100644 src/modules/objects/class_lcd.h delete mode 100644 src/modules/objects/class_lineedit.cpp delete mode 100644 src/modules/objects/class_lineedit.h delete mode 100644 src/modules/objects/class_list.cpp delete mode 100644 src/modules/objects/class_list.h delete mode 100644 src/modules/objects/class_listwidget.cpp delete mode 100644 src/modules/objects/class_listwidget.h delete mode 100644 src/modules/objects/class_mainwindow.cpp delete mode 100644 src/modules/objects/class_mainwindow.h delete mode 100644 src/modules/objects/class_memorybuffer.cpp delete mode 100644 src/modules/objects/class_memorybuffer.h delete mode 100644 src/modules/objects/class_menubar.cpp delete mode 100644 src/modules/objects/class_menubar.h delete mode 100644 src/modules/objects/class_multilineedit.cpp delete mode 100644 src/modules/objects/class_multilineedit.h delete mode 100644 src/modules/objects/class_painter.cpp delete mode 100644 src/modules/objects/class_painter.h delete mode 100644 src/modules/objects/class_pixmap.cpp delete mode 100644 src/modules/objects/class_pixmap.h delete mode 100644 src/modules/objects/class_popupmenu.cpp delete mode 100644 src/modules/objects/class_popupmenu.h delete mode 100644 src/modules/objects/class_process.cpp delete mode 100644 src/modules/objects/class_process.h delete mode 100644 src/modules/objects/class_progressbar.cpp delete mode 100644 src/modules/objects/class_progressbar.h delete mode 100644 src/modules/objects/class_radiobutton.cpp delete mode 100644 src/modules/objects/class_radiobutton.h delete mode 100644 src/modules/objects/class_slider.cpp delete mode 100644 src/modules/objects/class_slider.h delete mode 100644 src/modules/objects/class_socket.cpp delete mode 100644 src/modules/objects/class_socket.h delete mode 100644 src/modules/objects/class_spinbox.cpp delete mode 100644 src/modules/objects/class_spinbox.h delete mode 100644 src/modules/objects/class_sql.cpp delete mode 100644 src/modules/objects/class_sql.h delete mode 100644 src/modules/objects/class_tablewidget.cpp delete mode 100644 src/modules/objects/class_tablewidget.h delete mode 100644 src/modules/objects/class_tabwidget.cpp delete mode 100644 src/modules/objects/class_tabwidget.h delete mode 100644 src/modules/objects/class_tbrowser.cpp delete mode 100644 src/modules/objects/class_tbrowser.h delete mode 100644 src/modules/objects/class_toolbar.cpp delete mode 100644 src/modules/objects/class_toolbar.h delete mode 100644 src/modules/objects/class_toolbutton.cpp delete mode 100644 src/modules/objects/class_toolbutton.h delete mode 100644 src/modules/objects/class_trayicon.cpp delete mode 100644 src/modules/objects/class_trayicon.h delete mode 100644 src/modules/objects/class_treewidget.cpp delete mode 100644 src/modules/objects/class_treewidget.h delete mode 100644 src/modules/objects/class_treewidgetitem.cpp delete mode 100644 src/modules/objects/class_treewidgetitem.h delete mode 100644 src/modules/objects/class_vbox.cpp delete mode 100644 src/modules/objects/class_vbox.h delete mode 100644 src/modules/objects/class_widget.cpp delete mode 100644 src/modules/objects/class_widget.h delete mode 100644 src/modules/objects/class_window.cpp delete mode 100644 src/modules/objects/class_window.h delete mode 100644 src/modules/objects/class_wizard.cpp delete mode 100644 src/modules/objects/class_wizard.h delete mode 100644 src/modules/objects/class_workspace.cpp delete mode 100644 src/modules/objects/class_workspace.h delete mode 100644 src/modules/objects/class_wrapper.cpp delete mode 100644 src/modules/objects/class_wrapper.h delete mode 100644 src/modules/objects/class_xmlreader.cpp delete mode 100644 src/modules/objects/class_xmlreader.h create mode 100644 src/modules/options/OptionsInstanceManager.cpp create mode 100644 src/modules/options/OptionsInstanceManager.h create mode 100644 src/modules/options/OptionsWidgetContainer.cpp create mode 100644 src/modules/options/OptionsWidgetContainer.h create mode 100644 src/modules/options/OptionsWidget_alertsAndHighlighting.cpp create mode 100644 src/modules/options/OptionsWidget_alertsAndHighlighting.h create mode 100644 src/modules/options/OptionsWidget_antiSpam.cpp create mode 100644 src/modules/options/OptionsWidget_antiSpam.h create mode 100644 src/modules/options/OptionsWidget_avatar.cpp create mode 100644 src/modules/options/OptionsWidget_avatar.h create mode 100644 src/modules/options/OptionsWidget_away.cpp create mode 100644 src/modules/options/OptionsWidget_away.h create mode 100644 src/modules/options/OptionsWidget_channel.cpp create mode 100644 src/modules/options/OptionsWidget_channel.h create mode 100644 src/modules/options/OptionsWidget_connection.cpp create mode 100644 src/modules/options/OptionsWidget_connection.h create mode 100644 src/modules/options/OptionsWidget_ctcp.cpp create mode 100644 src/modules/options/OptionsWidget_ctcp.h create mode 100644 src/modules/options/OptionsWidget_ctcpFloodProtection.cpp create mode 100644 src/modules/options/OptionsWidget_ctcpFloodProtection.h create mode 100644 src/modules/options/OptionsWidget_dcc.cpp create mode 100644 src/modules/options/OptionsWidget_dcc.h create mode 100644 src/modules/options/OptionsWidget_general.cpp create mode 100644 src/modules/options/OptionsWidget_general.h create mode 100644 src/modules/options/OptionsWidget_identity.cpp create mode 100644 src/modules/options/OptionsWidget_identity.h create mode 100644 src/modules/options/OptionsWidget_ignore.cpp create mode 100644 src/modules/options/OptionsWidget_ignore.h create mode 100644 src/modules/options/OptionsWidget_input.cpp create mode 100644 src/modules/options/OptionsWidget_input.h create mode 100644 src/modules/options/OptionsWidget_interfaceFeatures.cpp create mode 100644 src/modules/options/OptionsWidget_interfaceFeatures.h create mode 100644 src/modules/options/OptionsWidget_irc.cpp create mode 100644 src/modules/options/OptionsWidget_irc.h create mode 100644 src/modules/options/OptionsWidget_ircOutput.cpp create mode 100644 src/modules/options/OptionsWidget_ircOutput.h create mode 100644 src/modules/options/OptionsWidget_ircView.cpp create mode 100644 src/modules/options/OptionsWidget_ircView.h create mode 100644 src/modules/options/OptionsWidget_lag.cpp create mode 100644 src/modules/options/OptionsWidget_lag.h create mode 100644 src/modules/options/OptionsWidget_logging.cpp create mode 100644 src/modules/options/OptionsWidget_logging.h create mode 100644 src/modules/options/OptionsWidget_mediaTypes.cpp create mode 100644 src/modules/options/OptionsWidget_mediaTypes.h create mode 100644 src/modules/options/OptionsWidget_message.cpp create mode 100644 src/modules/options/OptionsWidget_message.h create mode 100644 src/modules/options/OptionsWidget_nickserv.cpp create mode 100644 src/modules/options/OptionsWidget_nickserv.h create mode 100644 src/modules/options/OptionsWidget_notifier.cpp create mode 100644 src/modules/options/OptionsWidget_notifier.h create mode 100644 src/modules/options/OptionsWidget_notify.cpp create mode 100644 src/modules/options/OptionsWidget_notify.h create mode 100644 src/modules/options/OptionsWidget_protection.cpp create mode 100644 src/modules/options/OptionsWidget_protection.h create mode 100644 src/modules/options/OptionsWidget_proxy.cpp create mode 100644 src/modules/options/OptionsWidget_proxy.h create mode 100644 src/modules/options/OptionsWidget_query.cpp create mode 100644 src/modules/options/OptionsWidget_query.h create mode 100644 src/modules/options/OptionsWidget_servers.cpp create mode 100644 src/modules/options/OptionsWidget_servers.h create mode 100644 src/modules/options/OptionsWidget_sound.cpp create mode 100644 src/modules/options/OptionsWidget_sound.h create mode 100644 src/modules/options/OptionsWidget_textEncoding.cpp create mode 100644 src/modules/options/OptionsWidget_textEncoding.h create mode 100644 src/modules/options/OptionsWidget_textIcons.cpp create mode 100644 src/modules/options/OptionsWidget_textIcons.h create mode 100644 src/modules/options/OptionsWidget_theme.cpp create mode 100644 src/modules/options/OptionsWidget_theme.h create mode 100644 src/modules/options/OptionsWidget_tools.cpp create mode 100644 src/modules/options/OptionsWidget_tools.h create mode 100644 src/modules/options/OptionsWidget_topicLabel.cpp create mode 100644 src/modules/options/OptionsWidget_topicLabel.h create mode 100644 src/modules/options/OptionsWidget_tray.cpp create mode 100644 src/modules/options/OptionsWidget_tray.h create mode 100644 src/modules/options/OptionsWidget_uparser.cpp create mode 100644 src/modules/options/OptionsWidget_uparser.h create mode 100644 src/modules/options/OptionsWidget_urlHandlers.cpp create mode 100644 src/modules/options/OptionsWidget_urlHandlers.h create mode 100644 src/modules/options/OptionsWidget_userList.cpp create mode 100644 src/modules/options/OptionsWidget_userList.h create mode 100644 src/modules/options/OptionsWidget_windowList.cpp create mode 100644 src/modules/options/OptionsWidget_windowList.h delete mode 100644 src/modules/options/container.cpp delete mode 100644 src/modules/options/container.h delete mode 100644 src/modules/options/instances.cpp delete mode 100644 src/modules/options/instances.h delete mode 100644 src/modules/options/optw_antispam.cpp delete mode 100644 src/modules/options/optw_antispam.h delete mode 100644 src/modules/options/optw_avatar.cpp delete mode 100644 src/modules/options/optw_avatar.h delete mode 100644 src/modules/options/optw_away.cpp delete mode 100644 src/modules/options/optw_away.h delete mode 100644 src/modules/options/optw_channel.cpp delete mode 100644 src/modules/options/optw_channel.h delete mode 100644 src/modules/options/optw_connection.cpp delete mode 100644 src/modules/options/optw_connection.h delete mode 100644 src/modules/options/optw_ctcp.cpp delete mode 100644 src/modules/options/optw_ctcp.h delete mode 100644 src/modules/options/optw_ctcpfloodprotection.cpp delete mode 100644 src/modules/options/optw_ctcpfloodprotection.h delete mode 100644 src/modules/options/optw_dcc.cpp delete mode 100644 src/modules/options/optw_dcc.h delete mode 100644 src/modules/options/optw_generalopt.cpp delete mode 100644 src/modules/options/optw_generalopt.h delete mode 100644 src/modules/options/optw_highlighting.cpp delete mode 100644 src/modules/options/optw_highlighting.h delete mode 100644 src/modules/options/optw_identity.cpp delete mode 100644 src/modules/options/optw_identity.h delete mode 100644 src/modules/options/optw_ignore.cpp delete mode 100644 src/modules/options/optw_ignore.h delete mode 100644 src/modules/options/optw_input.cpp delete mode 100644 src/modules/options/optw_input.h delete mode 100644 src/modules/options/optw_interfacefeatures.cpp delete mode 100644 src/modules/options/optw_interfacefeatures.h delete mode 100644 src/modules/options/optw_interfacelookglobal.cpp delete mode 100644 src/modules/options/optw_interfacelookglobal.h delete mode 100644 src/modules/options/optw_irc.cpp delete mode 100644 src/modules/options/optw_irc.h delete mode 100644 src/modules/options/optw_ircoutput.cpp delete mode 100644 src/modules/options/optw_ircoutput.h delete mode 100644 src/modules/options/optw_ircview.cpp delete mode 100644 src/modules/options/optw_ircview.h delete mode 100644 src/modules/options/optw_lag.cpp delete mode 100644 src/modules/options/optw_lag.h delete mode 100644 src/modules/options/optw_logging.cpp delete mode 100644 src/modules/options/optw_logging.h delete mode 100644 src/modules/options/optw_mediatypes.cpp delete mode 100644 src/modules/options/optw_mediatypes.h delete mode 100644 src/modules/options/optw_messages.cpp delete mode 100644 src/modules/options/optw_messages.h delete mode 100644 src/modules/options/optw_nickserv.cpp delete mode 100644 src/modules/options/optw_nickserv.h delete mode 100644 src/modules/options/optw_notifier.cpp delete mode 100644 src/modules/options/optw_notifier.h delete mode 100644 src/modules/options/optw_notify.cpp delete mode 100644 src/modules/options/optw_notify.h delete mode 100644 src/modules/options/optw_protection.cpp delete mode 100644 src/modules/options/optw_protection.h delete mode 100644 src/modules/options/optw_proxy.cpp delete mode 100644 src/modules/options/optw_proxy.h delete mode 100644 src/modules/options/optw_query.cpp delete mode 100644 src/modules/options/optw_query.h delete mode 100644 src/modules/options/optw_servers.cpp delete mode 100644 src/modules/options/optw_servers.h delete mode 100644 src/modules/options/optw_sound.cpp delete mode 100644 src/modules/options/optw_sound.h delete mode 100644 src/modules/options/optw_textencoding.cpp delete mode 100644 src/modules/options/optw_textencoding.h delete mode 100644 src/modules/options/optw_texticons.cpp delete mode 100644 src/modules/options/optw_texticons.h delete mode 100644 src/modules/options/optw_tools.cpp delete mode 100644 src/modules/options/optw_tools.h delete mode 100644 src/modules/options/optw_topiclabel.cpp delete mode 100644 src/modules/options/optw_topiclabel.h delete mode 100644 src/modules/options/optw_tray.cpp delete mode 100644 src/modules/options/optw_tray.h delete mode 100644 src/modules/options/optw_uparser.cpp delete mode 100644 src/modules/options/optw_uparser.h delete mode 100644 src/modules/options/optw_urlhandlers.cpp delete mode 100644 src/modules/options/optw_urlhandlers.h delete mode 100644 src/modules/options/optw_userlist.cpp delete mode 100644 src/modules/options/optw_userlist.h delete mode 100644 src/modules/options/optw_windowlist.cpp delete mode 100644 src/modules/options/optw_windowlist.h create mode 100644 src/modules/popupeditor/PopupEditorWindow.cpp create mode 100644 src/modules/popupeditor/PopupEditorWindow.h delete mode 100644 src/modules/popupeditor/popupeditor.cpp delete mode 100644 src/modules/popupeditor/popupeditor.h create mode 100644 src/modules/raweditor/RawEditorWindow.cpp create mode 100644 src/modules/raweditor/RawEditorWindow.h delete mode 100644 src/modules/raweditor/raweditor.cpp delete mode 100644 src/modules/raweditor/raweditor.h create mode 100644 src/modules/reguser/RegisteredUserEntryDialog.cpp create mode 100644 src/modules/reguser/RegisteredUserEntryDialog.h create mode 100644 src/modules/reguser/RegistrationWizard.cpp create mode 100644 src/modules/reguser/RegistrationWizard.h delete mode 100644 src/modules/reguser/edituser.cpp delete mode 100644 src/modules/reguser/edituser.h delete mode 100644 src/modules/reguser/wizard.cpp delete mode 100644 src/modules/reguser/wizard.h create mode 100644 src/modules/rijndael/BlowFish.cpp create mode 100644 src/modules/rijndael/BlowFish.h create mode 100644 src/modules/rijndael/Rijndael.cpp create mode 100644 src/modules/rijndael/Rijndael.h delete mode 100644 src/modules/rijndael/ablowfish.cpp delete mode 100644 src/modules/rijndael/ablowfish.h delete mode 100644 src/modules/rijndael/rijndael.cpp delete mode 100644 src/modules/rijndael/rijndael.h create mode 100644 src/modules/setup/SetupWizard.cpp create mode 100644 src/modules/setup/SetupWizard.h delete mode 100644 src/modules/setup/setupwizard.cpp delete mode 100644 src/modules/setup/setupwizard.h create mode 100644 src/modules/sharedfileswindow/SharedFilesWindow.cpp create mode 100644 src/modules/sharedfileswindow/SharedFilesWindow.h delete mode 100644 src/modules/sharedfileswindow/sharedfileswindow.cpp delete mode 100644 src/modules/sharedfileswindow/sharedfileswindow.h create mode 100644 src/modules/spaste/SlowPasteController.cpp create mode 100644 src/modules/spaste/SlowPasteController.h delete mode 100644 src/modules/spaste/controller.cpp delete mode 100644 src/modules/spaste/controller.h create mode 100644 src/modules/system/Plugin.cpp create mode 100644 src/modules/system/Plugin.h delete mode 100644 src/modules/system/plugin.cpp delete mode 100644 src/modules/system/plugin.h create mode 100644 src/modules/term/TermWidget.cpp create mode 100644 src/modules/term/TermWidget.h create mode 100644 src/modules/term/TermWindow.cpp create mode 100644 src/modules/term/TermWindow.h delete mode 100644 src/modules/term/termwidget.cpp delete mode 100644 src/modules/term/termwidget.h delete mode 100644 src/modules/term/termwindow.cpp delete mode 100644 src/modules/term/termwindow.h create mode 100644 src/modules/theme/PackThemeDialog.cpp create mode 100644 src/modules/theme/PackThemeDialog.h create mode 100644 src/modules/theme/SaveThemeDialog.cpp create mode 100644 src/modules/theme/SaveThemeDialog.h create mode 100644 src/modules/theme/ThemeFunctions.cpp create mode 100644 src/modules/theme/ThemeFunctions.h delete mode 100644 src/modules/theme/packthemedialog.cpp delete mode 100644 src/modules/theme/packthemedialog.h delete mode 100644 src/modules/theme/savethemedialog.cpp delete mode 100644 src/modules/theme/savethemedialog.h delete mode 100644 src/modules/theme/themefunctions.cpp delete mode 100644 src/modules/theme/themefunctions.h create mode 100644 src/modules/toolbareditor/CustomizeToolBarsDialog.cpp create mode 100644 src/modules/toolbareditor/CustomizeToolBarsDialog.h delete mode 100644 src/modules/toolbareditor/toolbareditor.cpp delete mode 100644 src/modules/toolbareditor/toolbareditor.h create mode 100644 src/modules/torrent/KTorrentDbusInterface.cpp create mode 100644 src/modules/torrent/KTorrentDbusInterface.h create mode 100644 src/modules/torrent/StatusBarApplet.cpp create mode 100644 src/modules/torrent/StatusBarApplet.h create mode 100644 src/modules/torrent/TorrentInterface.cpp create mode 100644 src/modules/torrent/TorrentInterface.h delete mode 100644 src/modules/torrent/tc_interface.cpp delete mode 100644 src/modules/torrent/tc_interface.h delete mode 100644 src/modules/torrent/tc_ktorrentdbusinterface.cpp delete mode 100644 src/modules/torrent/tc_ktorrentdbusinterface.h delete mode 100644 src/modules/torrent/tc_statusbarapplet.cpp delete mode 100644 src/modules/torrent/tc_statusbarapplet.h create mode 100644 src/modules/upnp/Manager.cpp create mode 100644 src/modules/upnp/Manager.h create mode 100644 src/modules/upnp/RootService.cpp create mode 100644 src/modules/upnp/RootService.h create mode 100644 src/modules/upnp/Service.cpp create mode 100644 src/modules/upnp/Service.h create mode 100644 src/modules/upnp/SsdpConnection.cpp create mode 100644 src/modules/upnp/SsdpConnection.h create mode 100644 src/modules/upnp/WanConnectionService.cpp create mode 100644 src/modules/upnp/WanConnectionService.h create mode 100644 src/modules/upnp/XmlFunctions.cpp create mode 100644 src/modules/upnp/XmlFunctions.h delete mode 100644 src/modules/upnp/manager.cpp delete mode 100644 src/modules/upnp/manager.h delete mode 100644 src/modules/upnp/rootservice.cpp delete mode 100644 src/modules/upnp/rootservice.h delete mode 100644 src/modules/upnp/service.cpp delete mode 100644 src/modules/upnp/service.h delete mode 100644 src/modules/upnp/ssdpconnection.cpp delete mode 100644 src/modules/upnp/ssdpconnection.h delete mode 100644 src/modules/upnp/wanconnectionservice.cpp delete mode 100644 src/modules/upnp/wanconnectionservice.h delete mode 100644 src/modules/upnp/xmlfunctions.cpp delete mode 100644 src/modules/upnp/xmlfunctions.h create mode 100644 src/modules/window/UserWindow.cpp create mode 100644 src/modules/window/UserWindow.h delete mode 100644 src/modules/window/userwindow.cpp delete mode 100644 src/modules/window/userwindow.h (limited to 'src/modules') diff --git a/src/modules/about/AboutDialog.cpp b/src/modules/about/AboutDialog.cpp new file mode 100644 index 000000000..081ebecca --- /dev/null +++ b/src/modules/about/AboutDialog.cpp @@ -0,0 +1,246 @@ +//============================================================================= +// +// File : AboutDialog.cpp +// Creation date : Sun Jun 23 17:59:12 2002 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net) +// Copyright (C) 2008 Elvio Basello (hellvis69 at netsons dot org) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "AboutDialog.h" + +#include "kvi_defaults.h" +#include "KviLocale.h" +#include "KviApplication.h" +#include "KviFileUtils.h" +#include "kvi_sourcesdate.h" +#include "KviBuildInfo.h" +#include "KviOsInfo.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +extern AboutDialog * g_pAboutDialog; +/* +"KVIrc public releases :
\n" \ +"
\n" \ +"0.9.0
\n" \ +"Release date: 25.01.1999
\n" \ +"
\n" \ +"1.0.0 'Millennium'
\n" \ +"\"The net in your hands\"
\n" \ +"Release date: 21.12.1999
\n" \ +"
\n" \ +"2.0.0 'Phoenix'
\n" \ +"\"The client that can't make coffee\"
\n" \ +"Release date: 30.05.2000
\n" \ +"
\n" \ +"2.1.0 'Dark Star'
\n" \ +"\"The client that can't make coffee\"
\n" \ +"Release date: 30.01.2001
\n" \ +"
\n" \ +"2.1.1 'Monolith'
\n" \ +"\"A breath of fresh net\"
\n" \ +"Release date: 01.05.2001
\n" \ +"
3.0.0-xmas build: 24-12-2001\n" \ +"3.0.0-beta1: 24-06-2002\n " +"3.0.0 'Avatar'
\n" \ +"\"No slogan yet\"
\n" \ +"Release date: Still unknown
\n" \ +*/ + +#include "abouttext.inc" + +AboutDialog::AboutDialog() +: KviTalTabDialog(0) +{ + setWindowTitle(__tr2qs_ctx("About KVIrc...","about")); + setOkButton(__tr2qs_ctx("Close","about")); + + // About tab + QString buffer; + g_pApp->findImage(buffer,"kvi_splash.png"); + + QPixmap pix(buffer); + + QWidget * w = new QWidget(this); + QGridLayout * g = new QGridLayout(w); + + QLabel * l = new QLabel(w); + l->setFrameStyle(QFrame::WinPanel | QFrame::Sunken); + QPalette p = l->palette(); + p.setColor(backgroundRole(), Qt::black); + l->setPalette(p); + l->setAlignment(Qt::AlignCenter); + l->setPixmap(pix); + + g->addWidget(l,0,0); + + QString aboutString= "KVIrc " KVI_VERSION " '" KVI_RELEASE_NAME "'
"; + aboutString += __tr2qs_ctx("Forged by the KVIrc Development Team","about"); + + l = new QLabel(aboutString,w); + l->setAlignment(Qt::AlignCenter); + g->addWidget(l,1,0); + + addTab(w,__tr2qs_ctx("About","about")); + + + // Info tab + w = new QWidget(this); + g = new QGridLayout(w); + + QTextEdit * v = new QTextEdit(w); + v->setReadOnly(true); + g->addWidget(v,0,0); + + // Get info + QString infoString = "KVIrc " KVI_VERSION " '" KVI_RELEASE_NAME "'

"; + infoString += ""; + infoString += __tr2qs_ctx("Runtime Info","about"); + infoString += ":
"; + infoString += __tr2qs_ctx("System Name","about"); + infoString += ": "; + infoString += KviOsInfo::name(); +#ifndef COMPILE_ON_MAC + infoString += " "; + infoString += KviOsInfo::release(); +#endif + infoString += "
"; + infoString += __tr2qs_ctx("System Version","about"); + infoString += ": "; + infoString += KviOsInfo::version(); + infoString += "
"; + infoString += __tr2qs_ctx("Architecture","about"); + infoString += ": "; + infoString += KviOsInfo::machine(); + infoString += "

"; + infoString += ""; + infoString += __tr2qs_ctx("Build Info","about"); + infoString += ":
"; + infoString += __tr2qs_ctx("Build Date","about"); + infoString += ": "; + infoString += KviBuildInfo::buildDate(); + infoString += "
"; + infoString += __tr2qs_ctx("Sources Date","about"); + infoString += ": "; + infoString += KviBuildInfo::buildSourcesDate(); + infoString += "
"; + infoString += __tr2qs_ctx("Revision Number","about"); + infoString += ": "; + infoString += KviBuildInfo::buildRevision(); + infoString += "
"; + infoString += __tr2qs_ctx("System Name","about"); + infoString += ": "; + infoString += KviBuildInfo::buildSystem(); + infoString += "
"; + infoString += __tr2qs_ctx("CPU Name","about"); + infoString += ": "; + infoString += KviBuildInfo::buildCPU(); + infoString += "
"; + infoString += __tr2qs_ctx("Build Command","about"); + infoString += ": "; + infoString += KviBuildInfo::buildCommand(); + infoString += "
"; + infoString += __tr2qs_ctx("Build Flags","about"); + infoString += ":
   "; + QString flags = KviBuildInfo::buildFlags(); + infoString += flags.replace(QRegExp(";"),"
   "); + infoString += "
"; + infoString += __tr2qs_ctx("Compiler Name","about"); + infoString += ": "; + infoString += KviBuildInfo::buildCompiler(); + infoString += "
"; + infoString += __tr2qs_ctx("Compiler Flags","about"); + infoString += ": "; + infoString += KviBuildInfo::buildCompilerFlags(); + + v->setText(infoString); + + addTab(w,__tr2qs_ctx("Executable Information","about")); + + + // Honor & Glory tab + w = new QWidget(this); + g = new QGridLayout(w); + + v = new QTextEdit(w); + v->setReadOnly(true); + g->addWidget(v,0,0); + + v->setText(g_szAboutText); + + addTab(w,__tr2qs_ctx("Honor && Glory","about")); + + + // License tab + w = new QWidget(this); + g = new QGridLayout(w); + + v = new QTextEdit(w); + v->setReadOnly(true); + v->setWordWrapMode(QTextOption::NoWrap); + g->addWidget(v,0,0); + + QString szLicense; + + QString szLicensePath; + g_pApp->getGlobalKvircDirectory(szLicensePath,KviApplication::License,"COPYING"); + + if(!KviFileUtils::loadFile(szLicensePath,szLicense)) + { + szLicense = __tr2qs_ctx("Oops... Can't find the license file...\n" \ + "It MUST be included in the distribution...\n" \ + "Please report to ","about"); + } + + v->setText(szLicense); + + addTab(w,__tr2qs_ctx("License","about")); + + + connect(this,SIGNAL(applyButtonPressed()),this,SLOT(closeButtonPressed())); +} + +AboutDialog::~AboutDialog() +{ + g_pAboutDialog = 0; +} + +void AboutDialog::closeEvent(QCloseEvent *e) +{ + e->ignore(); + delete this; +} + +void AboutDialog::closeButtonPressed() +{ + delete this; +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "AboutDialog.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES + diff --git a/src/modules/about/AboutDialog.h b/src/modules/about/AboutDialog.h new file mode 100644 index 000000000..ab0ea628b --- /dev/null +++ b/src/modules/about/AboutDialog.h @@ -0,0 +1,41 @@ +#ifndef _ABOUTDIALOG_H_ +#define _ABOUTDIALOG_H_ +//============================================================================= +// +// File : AboutDialog.h +// Creation date : Sun Jun 23 17:59:13 2002 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviTalTabDialog.h" + +class AboutDialog : public KviTalTabDialog +{ + Q_OBJECT +public: + AboutDialog(); + ~AboutDialog(); +protected: + virtual void closeEvent(QCloseEvent *e); +protected slots: + void closeButtonPressed(); +}; + +#endif //_ABOUTDIALOG_H_ diff --git a/src/modules/about/CMakeLists.txt b/src/modules/about/CMakeLists.txt index 700ba497d..752adbf40 100644 --- a/src/modules/about/CMakeLists.txt +++ b/src/modules/about/CMakeLists.txt @@ -1,10 +1,10 @@ # CMakeLists for src/modules/about SET(kviabout_MOC_HDRS - aboutdialog.h + AboutDialog.h ) SET(kviabout_SRCS - aboutdialog.cpp + AboutDialog.cpp libkviabout.cpp ) diff --git a/src/modules/about/aboutdialog.cpp b/src/modules/about/aboutdialog.cpp deleted file mode 100644 index 3e3d7d9a9..000000000 --- a/src/modules/about/aboutdialog.cpp +++ /dev/null @@ -1,246 +0,0 @@ -//============================================================================= -// -// File : aboutdialog.cpp -// Creation date : Sun Jun 23 17:59:12 2002 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net) -// Copyright (C) 2008 Elvio Basello (hellvis69 at netsons dot org) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "aboutdialog.h" - -#include "kvi_defaults.h" -#include "KviLocale.h" -#include "KviApplication.h" -#include "KviFileUtils.h" -#include "kvi_sourcesdate.h" -#include "KviBuildInfo.h" -#include "KviOsInfo.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -extern KviAboutDialog * g_pAboutDialog; -/* -"KVIrc public releases :
\n" \ -"
\n" \ -"0.9.0
\n" \ -"Release date: 25.01.1999
\n" \ -"
\n" \ -"1.0.0 'Millennium'
\n" \ -"\"The net in your hands\"
\n" \ -"Release date: 21.12.1999
\n" \ -"
\n" \ -"2.0.0 'Phoenix'
\n" \ -"\"The client that can't make coffee\"
\n" \ -"Release date: 30.05.2000
\n" \ -"
\n" \ -"2.1.0 'Dark Star'
\n" \ -"\"The client that can't make coffee\"
\n" \ -"Release date: 30.01.2001
\n" \ -"
\n" \ -"2.1.1 'Monolith'
\n" \ -"\"A breath of fresh net\"
\n" \ -"Release date: 01.05.2001
\n" \ -"
3.0.0-xmas build: 24-12-2001\n" \ -"3.0.0-beta1: 24-06-2002\n " -"3.0.0 'Avatar'
\n" \ -"\"No slogan yet\"
\n" \ -"Release date: Still unknown
\n" \ -*/ - -#include "abouttext.inc" - -KviAboutDialog::KviAboutDialog() -: KviTalTabDialog(0) -{ - setWindowTitle(__tr2qs_ctx("About KVIrc...","about")); - setOkButton(__tr2qs_ctx("Close","about")); - - // About tab - QString buffer; - g_pApp->findImage(buffer,"kvi_splash.png"); - - QPixmap pix(buffer); - - QWidget * w = new QWidget(this); - QGridLayout * g = new QGridLayout(w); - - QLabel * l = new QLabel(w); - l->setFrameStyle(QFrame::WinPanel | QFrame::Sunken); - QPalette p = l->palette(); - p.setColor(backgroundRole(), Qt::black); - l->setPalette(p); - l->setAlignment(Qt::AlignCenter); - l->setPixmap(pix); - - g->addWidget(l,0,0); - - QString aboutString= "KVIrc " KVI_VERSION " '" KVI_RELEASE_NAME "'
"; - aboutString += __tr2qs_ctx("Forged by the KVIrc Development Team","about"); - - l = new QLabel(aboutString,w); - l->setAlignment(Qt::AlignCenter); - g->addWidget(l,1,0); - - addTab(w,__tr2qs_ctx("About","about")); - - - // Info tab - w = new QWidget(this); - g = new QGridLayout(w); - - QTextEdit * v = new QTextEdit(w); - v->setReadOnly(true); - g->addWidget(v,0,0); - - // Get info - QString infoString = "KVIrc " KVI_VERSION " '" KVI_RELEASE_NAME "'

"; - infoString += ""; - infoString += __tr2qs_ctx("Runtime Info","about"); - infoString += ":
"; - infoString += __tr2qs_ctx("System Name","about"); - infoString += ": "; - infoString += KviOsInfo::name(); -#ifndef COMPILE_ON_MAC - infoString += " "; - infoString += KviOsInfo::release(); -#endif - infoString += "
"; - infoString += __tr2qs_ctx("System Version","about"); - infoString += ": "; - infoString += KviOsInfo::version(); - infoString += "
"; - infoString += __tr2qs_ctx("Architecture","about"); - infoString += ": "; - infoString += KviOsInfo::machine(); - infoString += "

"; - infoString += ""; - infoString += __tr2qs_ctx("Build Info","about"); - infoString += ":
"; - infoString += __tr2qs_ctx("Build Date","about"); - infoString += ": "; - infoString += KviBuildInfo::buildDate(); - infoString += "
"; - infoString += __tr2qs_ctx("Sources Date","about"); - infoString += ": "; - infoString += KviBuildInfo::buildSourcesDate(); - infoString += "
"; - infoString += __tr2qs_ctx("Revision Number","about"); - infoString += ": "; - infoString += KviBuildInfo::buildRevision(); - infoString += "
"; - infoString += __tr2qs_ctx("System Name","about"); - infoString += ": "; - infoString += KviBuildInfo::buildSystem(); - infoString += "
"; - infoString += __tr2qs_ctx("CPU Name","about"); - infoString += ": "; - infoString += KviBuildInfo::buildCPU(); - infoString += "
"; - infoString += __tr2qs_ctx("Build Command","about"); - infoString += ": "; - infoString += KviBuildInfo::buildCommand(); - infoString += "
"; - infoString += __tr2qs_ctx("Build Flags","about"); - infoString += ":
   "; - QString flags = KviBuildInfo::buildFlags(); - infoString += flags.replace(QRegExp(";"),"
   "); - infoString += "
"; - infoString += __tr2qs_ctx("Compiler Name","about"); - infoString += ": "; - infoString += KviBuildInfo::buildCompiler(); - infoString += "
"; - infoString += __tr2qs_ctx("Compiler Flags","about"); - infoString += ": "; - infoString += KviBuildInfo::buildCompilerFlags(); - - v->setText(infoString); - - addTab(w,__tr2qs_ctx("Executable Information","about")); - - - // Honor & Glory tab - w = new QWidget(this); - g = new QGridLayout(w); - - v = new QTextEdit(w); - v->setReadOnly(true); - g->addWidget(v,0,0); - - v->setText(g_szAboutText); - - addTab(w,__tr2qs_ctx("Honor && Glory","about")); - - - // License tab - w = new QWidget(this); - g = new QGridLayout(w); - - v = new QTextEdit(w); - v->setReadOnly(true); - v->setWordWrapMode(QTextOption::NoWrap); - g->addWidget(v,0,0); - - QString szLicense; - - QString szLicensePath; - g_pApp->getGlobalKvircDirectory(szLicensePath,KviApplication::License,"COPYING"); - - if(!KviFileUtils::loadFile(szLicensePath,szLicense)) - { - szLicense = __tr2qs_ctx("Oops... Can't find the license file...\n" \ - "It MUST be included in the distribution...\n" \ - "Please report to ","about"); - } - - v->setText(szLicense); - - addTab(w,__tr2qs_ctx("License","about")); - - - connect(this,SIGNAL(applyButtonPressed()),this,SLOT(closeButtonPressed())); -} - -KviAboutDialog::~KviAboutDialog() -{ - g_pAboutDialog = 0; -} - -void KviAboutDialog::closeEvent(QCloseEvent *e) -{ - e->ignore(); - delete this; -} - -void KviAboutDialog::closeButtonPressed() -{ - delete this; -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "aboutdialog.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES - diff --git a/src/modules/about/aboutdialog.h b/src/modules/about/aboutdialog.h deleted file mode 100644 index 30cc6e730..000000000 --- a/src/modules/about/aboutdialog.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _ABOUTDIALOG_H_ -#define _ABOUTDIALOG_H_ -//============================================================================= -// -// File : aboutdialog.h -// Creation date : Sun Jun 23 17:59:13 2002 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "KviTalTabDialog.h" - -class KviAboutDialog : public KviTalTabDialog -{ - Q_OBJECT -public: - KviAboutDialog(); - ~KviAboutDialog(); -protected: - virtual void closeEvent(QCloseEvent *e); -protected slots: - void closeButtonPressed(); -}; - -#endif //_ABOUTDIALOG_H_ diff --git a/src/modules/about/libkviabout.cpp b/src/modules/about/libkviabout.cpp index cae11f43a..3239afc1b 100644 --- a/src/modules/about/libkviabout.cpp +++ b/src/modules/about/libkviabout.cpp @@ -25,12 +25,12 @@ // //============================================================================= -#include "aboutdialog.h" +#include "AboutDialog.h" #include "KviModule.h" #include "KviLocale.h" -KviAboutDialog * g_pAboutDialog = 0; +AboutDialog * g_pAboutDialog = 0; /* @doc: about.kvirc @@ -52,7 +52,7 @@ static bool about_kvs_command_kvirc(KviKvsModuleCommandCall *) { if(!g_pAboutDialog) { - g_pAboutDialog = new KviAboutDialog(); + g_pAboutDialog = new AboutDialog(); g_pAboutDialog->show(); } else { g_pAboutDialog->raise(); diff --git a/src/modules/actioneditor/ActionEditor.cpp b/src/modules/actioneditor/ActionEditor.cpp new file mode 100644 index 000000000..c20b762e7 --- /dev/null +++ b/src/modules/actioneditor/ActionEditor.cpp @@ -0,0 +1,939 @@ +//============================================================================= +// +// File : AliasEditorWindow.cpp +// Creation date : Tue 29 Dec 2004 02:45:59 2002 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2004-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the linkss of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= +#include "ActionEditor.h" + +#include "KviIconManager.h" +#include "KviOptions.h" +#include "KviLocale.h" +#include "KviImageDialog.h" +#include "KviConfigurationFile.h" +#include "KviFileUtils.h" +#include "KviScriptEditor.h" +#include "kvi_debug.h" +#include "KviApplication.h" +#include "KviQString.h" +#include "KviKvsAliasManager.h" +#include "KviFileDialog.h" +#include "KviActionManager.h" +#include "KviAction.h" +#include "KviKvsUserAction.h" +#include "KviCustomToolBarManager.h" +#include "KviTalVBox.h" +#include +#include "KviTalIconAndRichTextItemDelegate.h" +#include "kvi_fileextensions.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +extern ActionEditorWindow * g_pActionEditorWindow; + +static QString g_szLastEditedAction; + +#define LVI_ICON_SIZE 32 +#define LVI_BORDER 4 +#define LVI_SPACING 8 +#define LVI_MINIMUM_CELL_WIDTH (LVI_MINIMUM_TEXT_WIDTH + LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING + LVI_BORDER) + +ActionEditorTreeWidgetItem::ActionEditorTreeWidgetItem(QTreeWidget * v,ActionData * a) +: QTreeWidgetItem(v) +{ + m_pActionData = a; + m_pTreeWidget = v; + //setFlags(Qt::ItemIsUserSelectable); + QString t = "" + m_pActionData->m_szName + ""; + t += "
" + m_pActionData->m_szVisibleName + ""; + m_szKey = m_pActionData->m_szName.toUpper(); + setText(0,t); + QPixmap * p = g_pIconManager->getBigIcon(m_pActionData->m_szBigIcon); + if(p)setIcon(0,*p); +} + +ActionEditorTreeWidgetItem::~ActionEditorTreeWidgetItem() +{ + delete m_pActionData; +} + + +QString ActionEditorTreeWidgetItem::key(int,bool) const +{ + return m_szKey; +} + +SingleActionEditor::SingleActionEditor(QWidget * par,ActionEditor * ed) +: QWidget(par) +{ + m_pActionEditor = ed; + m_pActionData = 0; + + QGridLayout * g = new QGridLayout(this); + + QLabel * l = new QLabel(__tr2qs_ctx("Name:","editor"),this); + g->addWidget(l,0,0); + m_pNameEdit = new QLineEdit(this); + g->addWidget(m_pNameEdit,0,1); + m_pNameEdit->setToolTip(__tr2qs_ctx("Internal unique name for the action","editor")); + + l = new QLabel(__tr2qs_ctx("Label:","editor"),this); + g->addWidget(l,1,0); + m_pVisibleNameEdit = new QLineEdit(this); + g->addWidget(m_pVisibleNameEdit,1,1); + m_pVisibleNameEdit->setToolTip(__tr2qs_ctx("Visible name for this action.
This string will be displayed to the user so it is a good idea to use $tr() here","editor")); + + + QTabWidget * tw = new QTabWidget(this); + g->addWidget(tw,2,0,1,2); +// g->addMultiCellWidget(tw,2,2,0,1); + + // code tab + QWidget * tab = new QWidget(tw); + QGridLayout * gl = new QGridLayout(tab); + + m_pScriptEditor = KviScriptEditor::createInstance(tab); + gl->addWidget(m_pScriptEditor,0,0); + m_pScriptEditor->setToolTip(__tr2qs_ctx("Action code","editor")); + + tw->addTab(tab,__tr2qs_ctx("Code","editor")); + + // properties tab + tab = new QWidget(tw); + gl = new QGridLayout(tab); + + l = new QLabel(__tr2qs_ctx("Category:","editor"),tab); + gl->addWidget(l,0,0); + m_pCategoryCombo = new QComboBox(tab); + gl->addWidget(m_pCategoryCombo,0,1,1,3); + //gl->addMultiCellWidget(m_pCategoryCombo,0,0,1,3); + m_pCategoryCombo->setToolTip(__tr2qs_ctx("Choose the category that best fits for this action","editor")); + + l = new QLabel(__tr2qs_ctx("Description:","editor"),tab); + gl->addWidget(l,1,0); + m_pDescriptionEdit = new QLineEdit(tab); + gl->addWidget(m_pDescriptionEdit,1,1,1,3); +// gl->addMultiCellWidget(m_pDescriptionEdit,1,1,1,3); + m_pDescriptionEdit->setToolTip(__tr2qs_ctx("Visible short description for this action.
This string will be displayed to the user so it is a good idea to use $tr() here","editor")); + + l = new QLabel(__tr2qs_ctx("Small Icon:","editor"),tab); + gl->addWidget(l,2,0); + m_pSmallIconEdit = new QLineEdit(tab); + gl->addWidget(m_pSmallIconEdit,2,1); + m_pSmallIconButton = new QToolButton(tab); + m_pSmallIconButton->setMinimumSize(QSize(20,20)); + connect(m_pSmallIconButton,SIGNAL(clicked()),this,SLOT(chooseSmallIcon())); + gl->addWidget(m_pSmallIconButton,2,2); + QString s= __tr2qs_ctx("The small icon associated to this action.
" \ + "It will appear at least in the popup menus when this action is inserted.
" \ + "It has to be 16x16 pixels.","editor"); + m_pSmallIconEdit->setToolTip(s); + m_pSmallIconButton->setToolTip(s); + + l = new QLabel(__tr2qs_ctx("Big Icon:","editor"),tab); + gl->addWidget(l,3,0); + m_pBigIconEdit = new QLineEdit(tab); + gl->addWidget(m_pBigIconEdit,3,1); + m_pBigIconButton = new QToolButton(tab); + m_pBigIconButton->setMinimumSize(QSize(48,48)); + m_pBigIconButton->setIconSize(QSize(32,32)); + connect(m_pBigIconButton,SIGNAL(clicked()),this,SLOT(chooseBigIcon())); + gl->addWidget(m_pBigIconButton,3,2,2,2); +// gl->addMultiCellWidget(m_pBigIconButton,3,4,2,3); + s = __tr2qs_ctx("The big icon associated to this action.
" \ + "It will appear at least in the toolbar buttons when this action is inserted.
" \ + "It has to be 32x32 pixels.","editor"); + m_pBigIconEdit->setToolTip(s); + m_pBigIconButton->setToolTip(s); + + l = new QLabel(__tr2qs_ctx("Key Sequence:","editor"),tab); + gl->addWidget(l,4,0,2,1); +// gl->addMultiCellWidget(l,4,5,0,0); + m_pKeySequenceEdit = new QLineEdit(tab); + gl->addWidget(m_pKeySequenceEdit,4,1,2,1); +// gl->addMultiCellWidget(m_pKeySequenceEdit,4,5,1,1); + m_pKeySequenceEdit->setToolTip(__tr2qs_ctx("Optional keyboard sequence that will activate this action.
" \ + "The sequence has to be expressed as a string of up to four key codes separated by commas " \ + "eventually combined with the modifiers \"Ctrl\",\"Shift\",\"Alt\" and \"Meta\".
" \ + "Examples of such sequences are \"Ctrl+X\", \"Ctrl+Alt+Z\", \"Ctrl+X,Ctrl+C\" ...","editor")); + + l = new QLabel(tab); + gl->addWidget(l,6,0,1,4); +// gl->addMultiCellWidget(l,6,6,0,3); + + gl->setColumnStretch(1,1); + gl->setRowStretch(6,1); + + + tw->addTab(tab,__tr2qs_ctx("Properties","editor")); + + + + // flags tab + tab = new QWidget(tw); + gl = new QGridLayout(tab); + + + m_pNeedsContextCheck = new QCheckBox(__tr2qs_ctx("Needs IRC Context","editor"),tab); + connect(m_pNeedsContextCheck,SIGNAL(toggled(bool)),this,SLOT(needsContextCheckToggled(bool))); + m_pNeedsContextCheck->setToolTip(__tr2qs_ctx("Check this option if this action should be enabled only when " \ + "the active window belongs to an irc context","editor")); + gl->addWidget(m_pNeedsContextCheck,0,0,1,4); + + + l = new QLabel(tab); + l->setMinimumWidth(40); + gl->addWidget(l,1,0); + + m_pNeedsConnectionCheck = new QCheckBox(__tr2qs_ctx("Needs IRC Connection","editor"),tab); + connect(m_pNeedsConnectionCheck,SIGNAL(toggled(bool)),this,SLOT(needsConnectionCheckToggled(bool))); + m_pNeedsConnectionCheck->setToolTip(__tr2qs_ctx("Check this option if this action should be enabled only when " \ + "the active window has an active IRC connection","editor")); + gl->addWidget(m_pNeedsConnectionCheck,1,1,1,3); + + + l = new QLabel(tab); + l->setMinimumWidth(40); + gl->addWidget(l,2,1); + + m_pEnableAtLoginCheck = new QCheckBox(__tr2qs_ctx("Enable at Login","editor"),tab); + m_pEnableAtLoginCheck->setToolTip(__tr2qs_ctx("Check this option if this action should be enabled also during " \ + "the login operations (so when the logical IRC connection hasn't been estabilished yet)","editor")); + gl->addWidget(m_pEnableAtLoginCheck,2,2,1,2); + + m_pSpecificWindowsCheck = new QCheckBox(__tr2qs_ctx("Enable Only in Specified Windows","editor"),tab); + connect(m_pSpecificWindowsCheck,SIGNAL(toggled(bool)),this,SLOT(specificWindowsCheckToggled(bool))); + m_pSpecificWindowsCheck->setToolTip(__tr2qs_ctx("Check this option if this action should be enabled only when " \ + "the active window is of a specified type","editor")); + gl->addWidget(m_pSpecificWindowsCheck,3,0,1,4); + + + m_pWindowConsoleCheck = new QCheckBox(__tr2qs_ctx("Enable in Console Windows","editor"),tab); + m_pWindowConsoleCheck->setToolTip(__tr2qs_ctx("Check this option if this action should be enabled only when " \ + "the active window is a console","editor")); + connect(m_pWindowConsoleCheck,SIGNAL(toggled(bool)),this,SLOT(channelQueryOrConsoleWindowCheckToggled(bool))); + gl->addWidget(m_pWindowConsoleCheck,4,1,1,3); + + m_pConsoleOnlyIfUsersSelectedCheck = new QCheckBox(__tr2qs_ctx("Only If There Are Selected Users","editor"),tab); + m_pConsoleOnlyIfUsersSelectedCheck->setToolTip(__tr2qs_ctx("This will enable the action only if there are " \ + "selected users in the active window","editor")); + gl->addWidget(m_pConsoleOnlyIfUsersSelectedCheck,5,2,1,2); + + m_pWindowChannelCheck = new QCheckBox(__tr2qs_ctx("Enable in Channel Windows","editor"),tab); + m_pWindowChannelCheck->setToolTip(__tr2qs_ctx("Check this option if this action should be enabled only when " \ + "the active window is a channel","editor")); + connect(m_pWindowChannelCheck,SIGNAL(toggled(bool)),this,SLOT(channelQueryOrConsoleWindowCheckToggled(bool))); + gl->addWidget(m_pWindowChannelCheck,6,1,1,3); + + m_pChannelOnlyIfUsersSelectedCheck = new QCheckBox(__tr2qs_ctx("Only If There Are Selected Users","editor"),tab); + m_pChannelOnlyIfUsersSelectedCheck->setToolTip(__tr2qs_ctx("This will enable the action only if there are " \ + "selected users in the active window","editor")); + gl->addWidget(m_pChannelOnlyIfUsersSelectedCheck,7,2,1,2); + + m_pWindowQueryCheck = new QCheckBox(__tr2qs_ctx("Enable in Query Windows","editor"),tab); + m_pWindowQueryCheck->setToolTip(__tr2qs_ctx("Check this option if this action should be enabled only when " \ + "the active window is a query","editor")); + connect(m_pWindowQueryCheck,SIGNAL(toggled(bool)),this,SLOT(channelQueryOrConsoleWindowCheckToggled(bool))); + gl->addWidget(m_pWindowQueryCheck,8,1,1,3); + + m_pQueryOnlyIfUsersSelectedCheck = new QCheckBox(__tr2qs_ctx("Only If There Are Selected Users","editor"),tab); + m_pQueryOnlyIfUsersSelectedCheck->setToolTip(__tr2qs_ctx("This will enable the action only if there are " \ + "selected users in the active window","editor")); + gl->addWidget(m_pQueryOnlyIfUsersSelectedCheck,9,2,1,2); + + m_pWindowDccChatCheck = new QCheckBox(__tr2qs_ctx("Enable in DCC Chat Windows","editor"),tab); + m_pWindowDccChatCheck->setToolTip(__tr2qs_ctx("Check this option if this action should be enabled only when " \ + "the active window is a dcc chat","editor")); + gl->addWidget(m_pWindowDccChatCheck,10,1,1,2); + + l = new QLabel(tab); + gl->addWidget(l,11,0,1,4); + gl->setColumnStretch(3,1); + gl->setRowStretch(11,1); + + tw->addTab(tab,__tr2qs_ctx("Flags","editor")); + tw->setCurrentIndex(0); + + g->setRowStretch(2,1); + g->setColumnStretch(1,1); + + KviPointerHashTableIterator it(*(KviActionManager::instance()->categories())); + while(KviActionCategory * ac = it.current()) + { + m_pCategoryCombo->addItem(ac->visibleName() + " (" + ac->name() + ")"); + ++it; + } +} + +SingleActionEditor::~SingleActionEditor() +{ +} + +void SingleActionEditor::channelQueryOrConsoleWindowCheckToggled(bool) +{ + m_pChannelOnlyIfUsersSelectedCheck->setEnabled(m_pWindowChannelCheck->isChecked()); + m_pChannelOnlyIfUsersSelectedCheck->setChecked(false); + m_pQueryOnlyIfUsersSelectedCheck->setEnabled(m_pWindowQueryCheck->isChecked()); + m_pQueryOnlyIfUsersSelectedCheck->setChecked(false); + m_pConsoleOnlyIfUsersSelectedCheck->setEnabled(m_pWindowConsoleCheck->isChecked()); + m_pConsoleOnlyIfUsersSelectedCheck->setChecked(false); +} + +void SingleActionEditor::needsContextCheckToggled(bool) +{ + m_pEnableAtLoginCheck->setChecked(false); + m_pEnableAtLoginCheck->setEnabled(false); + m_pNeedsConnectionCheck->setChecked(false); + m_pNeedsConnectionCheck->setEnabled(m_pNeedsContextCheck->isChecked()); +} + +void SingleActionEditor::needsConnectionCheckToggled(bool) +{ + m_pEnableAtLoginCheck->setChecked(false); + m_pEnableAtLoginCheck->setEnabled(m_pNeedsConnectionCheck->isChecked()); +} + +void SingleActionEditor::specificWindowsCheckToggled(bool) +{ + m_pWindowConsoleCheck->setChecked(false); + m_pWindowChannelCheck->setChecked(false); + m_pWindowQueryCheck->setChecked(false); + m_pWindowDccChatCheck->setChecked(false); + m_pQueryOnlyIfUsersSelectedCheck->setChecked(false); + m_pChannelOnlyIfUsersSelectedCheck->setChecked(false); + m_pConsoleOnlyIfUsersSelectedCheck->setChecked(false); + m_pQueryOnlyIfUsersSelectedCheck->setEnabled(false); + m_pChannelOnlyIfUsersSelectedCheck->setEnabled(false); + m_pConsoleOnlyIfUsersSelectedCheck->setEnabled(false); + bool b = m_pSpecificWindowsCheck->isChecked(); + m_pWindowConsoleCheck->setEnabled(b); + m_pWindowChannelCheck->setEnabled(b); + m_pWindowQueryCheck->setEnabled(b); + m_pWindowDccChatCheck->setEnabled(b); +} + +void SingleActionEditor::displaySmallIcon(const QString &szIconId) +{ + QPixmap * pix = g_pIconManager->getImage(szIconId); + + if(pix) + { + m_pSmallIconEdit->setText(szIconId); + m_pSmallIconButton->setIcon(QIcon(*pix)); + } else { + m_pSmallIconEdit->setText(QString()); + m_pSmallIconButton->setIcon(QIcon()); + } + +} + +void SingleActionEditor::displayBigIcon(const QString &szIconId) +{ + QPixmap * pix = g_pIconManager->getImage(szIconId); + + if(pix) + { + m_pBigIconEdit->setText(szIconId); + m_pBigIconButton->setIcon(QIcon(*pix)); + } else { + m_pBigIconEdit->setText(QString()); + m_pBigIconButton->setIcon(QIcon()); + } +} + +void SingleActionEditor::chooseSmallIcon() +{ + if(!m_pActionData)return; + KviImageDialog * d = new KviImageDialog(this); + int ret = d->exec(); + QString s = d->selectedImage(); + delete d; + if(ret != QDialog::Accepted) + return; + + displaySmallIcon(s); +} + +void SingleActionEditor::chooseBigIcon() +{ + if(!m_pActionData)return; + KviImageDialog * d = new KviImageDialog(this,QString(),KID_TYPE_ALL,KID_TYPE_FULL_PATH); + int ret = d->exec(); + QString s = d->selectedImage(); + delete d; + if(ret != QDialog::Accepted) + return; + + displayBigIcon(s); +} + +void SingleActionEditor::setActionData(ActionData * d) +{ + m_pActionData = d; + + if(d) + { + unsigned int uOldFlags = d->m_uFlags; + d->m_uFlags = KviAction::validateFlags(d->m_uFlags); + if(d->m_uFlags != uOldFlags) + qDebug("invalid action flags in SingleActionEditor::setActionData(): %d fixed to %d",uOldFlags,d->m_uFlags); + + m_pNameEdit->setText(d->m_szName); + m_pNameEdit->setEnabled(true); + m_pVisibleNameEdit->setText(d->m_szVisibleName); + m_pVisibleNameEdit->setEnabled(true); + m_pCategoryCombo->setEnabled(true); + int i; + for(i=0;icount();i++) + { + QString t = m_pCategoryCombo->itemText(i); + int idx = t.lastIndexOf('('); + QString r = t.right(t.length() - (idx + 1)); + QString r2 = r.left(r.length() - 1); + r2.trimmed(); + if(r2 == d->m_szCategory) + { + m_pCategoryCombo->setCurrentIndex(i); + break; + } + } + if(i == m_pCategoryCombo->count()) + { + m_pCategoryCombo->setCurrentIndex(0); + } + m_pScriptEditor->setText(d->m_szScriptCode); + m_pScriptEditor->setEnabled(true); + m_pKeySequenceEdit->setText(d->m_szKeySequence); + m_pKeySequenceEdit->setEnabled(true); + m_pDescriptionEdit->setText(d->m_szDescription); + m_pDescriptionEdit->setEnabled(true); + m_pSmallIconEdit->setEnabled(true); + m_pBigIconEdit->setEnabled(true); + displaySmallIcon(d->m_szSmallIcon); + displayBigIcon(d->m_szBigIcon); + m_pSmallIconButton->setEnabled(true); + m_pBigIconButton->setEnabled(true); + m_pNeedsContextCheck->setEnabled(true); + bool b = (d->m_uFlags & KviAction::NeedsContext) || (d->m_uFlags & KviAction::NeedsConnection); + m_pNeedsContextCheck->setChecked(b); + + m_pNeedsConnectionCheck->setEnabled(b); + b = (d->m_uFlags & KviAction::NeedsContext) && (d->m_uFlags & KviAction::NeedsConnection); + m_pNeedsConnectionCheck->setChecked(b); + + m_pEnableAtLoginCheck->setEnabled(b); + m_pEnableAtLoginCheck->setChecked(b && (d->m_uFlags & KviAction::EnableAtLogin)); + + m_pSpecificWindowsCheck->setEnabled(true); + b = d->m_uFlags & KviAction::InternalWindowMask; + m_pSpecificWindowsCheck->setChecked(b); + + m_pWindowConsoleCheck->setEnabled(b); + m_pWindowChannelCheck->setEnabled(b); + m_pWindowQueryCheck->setEnabled(b); + m_pWindowDccChatCheck->setEnabled(b); + b = d->m_uFlags & KviAction::WindowConsole; + m_pWindowConsoleCheck->setChecked(b); + m_pConsoleOnlyIfUsersSelectedCheck->setEnabled(b); + m_pConsoleOnlyIfUsersSelectedCheck->setChecked(b && (d->m_uFlags & KviAction::WindowOnlyIfUsersSelected)); + b = d->m_uFlags & KviAction::WindowChannel; + m_pWindowChannelCheck->setChecked(b); + m_pChannelOnlyIfUsersSelectedCheck->setEnabled(b); + m_pChannelOnlyIfUsersSelectedCheck->setChecked(b && (d->m_uFlags & KviAction::WindowOnlyIfUsersSelected)); + b = d->m_uFlags & KviAction::WindowQuery; + m_pWindowQueryCheck->setChecked(b); + m_pQueryOnlyIfUsersSelectedCheck->setEnabled(b); + m_pQueryOnlyIfUsersSelectedCheck->setChecked(b && (d->m_uFlags & KviAction::WindowOnlyIfUsersSelected)); + m_pWindowDccChatCheck->setChecked(d->m_uFlags & KviAction::WindowDccChat); + } else { + m_pNameEdit->setText(""); + m_pNameEdit->setEnabled(false); + m_pVisibleNameEdit->setText(""); + m_pVisibleNameEdit->setEnabled(false); + m_pCategoryCombo->setEnabled(false); + m_pScriptEditor->setText(""); + m_pScriptEditor->setEnabled(false); + m_pKeySequenceEdit->setText(""); + m_pKeySequenceEdit->setEnabled(false); + m_pDescriptionEdit->setText(""); + m_pDescriptionEdit->setEnabled(false); + m_pSmallIconEdit->setText(""); + m_pSmallIconEdit->setEnabled(false); + m_pBigIconEdit->setText(""); + m_pBigIconEdit->setEnabled(false); + m_pSmallIconButton->setIcon(QIcon()); + m_pSmallIconButton->setEnabled(false); + m_pBigIconButton->setIcon(QPixmap()); + m_pBigIconButton->setEnabled(false); + m_pNeedsContextCheck->setChecked(false); + m_pNeedsContextCheck->setEnabled(false); + m_pNeedsConnectionCheck->setChecked(false); + m_pNeedsConnectionCheck->setEnabled(false); + m_pEnableAtLoginCheck->setChecked(false); + m_pEnableAtLoginCheck->setEnabled(false); + m_pWindowConsoleCheck->setChecked(false); + m_pWindowConsoleCheck->setEnabled(false); + m_pWindowChannelCheck->setChecked(false); + m_pWindowChannelCheck->setEnabled(false); + m_pWindowQueryCheck->setChecked(false); + m_pWindowQueryCheck->setEnabled(false); + m_pWindowDccChatCheck->setChecked(false); + m_pWindowDccChatCheck->setEnabled(false); + m_pSpecificWindowsCheck->setChecked(false); + m_pSpecificWindowsCheck->setEnabled(false); + m_pQueryOnlyIfUsersSelectedCheck->setChecked(false); + m_pChannelOnlyIfUsersSelectedCheck->setChecked(false); + m_pConsoleOnlyIfUsersSelectedCheck->setChecked(false); + m_pQueryOnlyIfUsersSelectedCheck->setEnabled(false); + m_pChannelOnlyIfUsersSelectedCheck->setEnabled(false); + m_pConsoleOnlyIfUsersSelectedCheck->setEnabled(false); + } +} + +void SingleActionEditor::commit() +{ + if(!m_pActionData)return; + + QString tmp = m_pNameEdit->text(); + if(tmp != m_pActionData->m_szName) + { + int idx = 1; + while(KviActionManager::instance()->coreActionExists(tmp) || m_pActionEditor->actionExists(tmp)) + { + QString tmp2; + tmp2.setNum(idx); + tmp = m_pNameEdit->text(); + tmp.append(tmp2); + idx++; + } + } + + m_pActionData->m_szName = tmp; + m_pScriptEditor->getText(m_pActionData->m_szScriptCode); + m_pActionData->m_szVisibleName = m_pVisibleNameEdit->text(); + m_pActionData->m_szDescription = m_pDescriptionEdit->text(); + m_pActionData->m_szBigIcon = m_pBigIconEdit->text(); + m_pActionData->m_szSmallIcon = m_pSmallIconEdit->text(); + m_pActionData->m_szKeySequence = m_pKeySequenceEdit->text(); + QString szCat = m_pCategoryCombo->currentText(); + int idx = szCat.lastIndexOf(')'); + if(idx != -1)m_pActionData->m_szCategory = szCat.left(idx); + else m_pActionData->m_szCategory = szCat; + idx = m_pActionData->m_szCategory.lastIndexOf('('); + if(idx != -1)m_pActionData->m_szCategory.remove(0,idx+1); + m_pActionData->m_uFlags = 0; + if(m_pNeedsContextCheck->isChecked()) + { + m_pActionData->m_uFlags |= KviAction::NeedsContext; + if(m_pNeedsConnectionCheck->isChecked()) + { + m_pActionData->m_uFlags |= KviAction::NeedsConnection; + if(m_pEnableAtLoginCheck->isChecked())m_pActionData->m_uFlags |= KviAction::EnableAtLogin; + } + + } + if(m_pSpecificWindowsCheck->isChecked()) + { + if(m_pWindowConsoleCheck->isChecked())m_pActionData->m_uFlags |= KviAction::WindowConsole; + if(m_pWindowChannelCheck->isChecked())m_pActionData->m_uFlags |= KviAction::WindowChannel; + if(m_pWindowQueryCheck->isChecked())m_pActionData->m_uFlags |= KviAction::WindowQuery; + if(m_pWindowDccChatCheck->isChecked())m_pActionData->m_uFlags |= KviAction::WindowDccChat; + if(m_pActionData->m_uFlags & KviAction::InternalWindowMask) + { + if(m_pConsoleOnlyIfUsersSelectedCheck->isChecked() || + m_pChannelOnlyIfUsersSelectedCheck->isChecked() || + m_pQueryOnlyIfUsersSelectedCheck->isChecked()) + { + m_pActionData->m_uFlags |= KviAction::WindowOnlyIfUsersSelected; + } + } + } + + unsigned int uOldFlags = m_pActionData->m_uFlags; + m_pActionData->m_uFlags = KviAction::validateFlags(m_pActionData->m_uFlags); + if(m_pActionData->m_uFlags != uOldFlags) + qDebug("invalid action flags in SingleActionEditor::commit(): %d fixed to %d",uOldFlags,m_pActionData->m_uFlags); +} + + +ActionEditorTreeView::ActionEditorTreeView(QWidget * pParent) +: QTreeWidget(pParent) +{ + setColumnCount (1); + setHeaderLabel(__tr2qs_ctx("Action","editor")); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setSortingEnabled(true); + int iWidth = viewport()->width(); + if(iWidth < LVI_MINIMUM_CELL_WIDTH)iWidth = LVI_MINIMUM_CELL_WIDTH; + setRootIsDecorated(false); + setColumnWidth(0,iWidth); + +} + +ActionEditorTreeView::~ActionEditorTreeView() +{ +} + +void ActionEditorTreeView::resizeEvent(QResizeEvent * e) +{ + QTreeWidget::resizeEvent(e); + int iWidth = viewport()->width(); + if(iWidth < LVI_MINIMUM_CELL_WIDTH)iWidth = LVI_MINIMUM_CELL_WIDTH; + setColumnWidth(0,iWidth); +} + + +ActionEditor::ActionEditor(QWidget * par) +: QWidget(par) +{ + + QGridLayout * l = new QGridLayout(this); + m_pSplitter = new QSplitter(Qt::Horizontal,this); + m_pSplitter->setChildrenCollapsible(false); + l->addWidget(m_pSplitter,0,0); + + + KviTalVBox * box = new KviTalVBox(m_pSplitter); + m_pTreeWidget = new ActionEditorTreeView(box); + KviTalIconAndRichTextItemDelegate *itemDelegate=new KviTalIconAndRichTextItemDelegate(m_pTreeWidget); + m_pTreeWidget->setItemDelegate(itemDelegate); + //m_pTreeWidget->setShowSortIndicator(true); + m_pTreeWidget->setFocusPolicy(Qt::StrongFocus); + connect(m_pTreeWidget,SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),this,SLOT(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *))); + + m_pNewActionButton = new QPushButton(__tr2qs_ctx("New Action","editor"),box); + connect(m_pNewActionButton,SIGNAL(clicked()),this,SLOT(newAction())); + + m_pDeleteActionsButton = new QPushButton(__tr2qs_ctx("Delete Actions","editor"),box); + connect(m_pDeleteActionsButton,SIGNAL(clicked()),this,SLOT(deleteActions())); + + m_pExportActionsButton = new QPushButton(__tr2qs_ctx("Export Actions...","editor"),box); + connect(m_pExportActionsButton,SIGNAL(clicked()),this,SLOT(exportActions())); + + box->setSpacing(1); + + m_pSingleActionEditor = new SingleActionEditor(m_pSplitter,this); + + ActionEditorTreeWidgetItem * last = 0; + ActionEditorTreeWidgetItem * first = 0; + + KviPointerHashTableIterator it(*(KviActionManager::instance()->actions())); + while(KviAction * a = it.current()) + { + if(a->isKviUserActionNeverOverrideThis()) + { + ActionData * ad = new ActionData( + a->name(), + ((KviKvsUserAction *)a)->scriptCode(), + ((KviKvsUserAction *)a)->visibleNameCode(), + ((KviKvsUserAction *)a)->descriptionCode(), + a->category() ? a->category()->name() : KviActionManager::categoryGeneric()->name(), + a->bigIconId(), + a->smallIconId(), + a->flags(), + a->keySequence(), + 0 + ); + ActionEditorTreeWidgetItem * lvi = new ActionEditorTreeWidgetItem(m_pTreeWidget,ad); + ad->m_pItem = lvi; + if(ad->m_szName == g_szLastEditedAction) + last = lvi; + if(!first) + first = lvi; + } + ++it; + } + + if(!last)last = first; // try to sleect the first one then + + if(last) + { + m_pTreeWidget->setCurrentItem(last); + currentItemChanged(last,last); + } else { + currentItemChanged(0,0); + } + +} + +ActionEditor::~ActionEditor() +{ +} + +void ActionEditor::exportActions() +{ + QString szName = QDir::homePath(); + if(!szName.endsWith(QString(KVI_PATH_SEPARATOR)))szName += KVI_PATH_SEPARATOR; + szName += "myactions.kvs"; + + QString szFile; + + if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs_ctx("Choose a Filename - KVIrc","editor"),szName,KVI_FILTER_SCRIPT,true,true,true))return; + + QString szCode; + + for (int i=0;itopLevelItemCount();i++) + { + if(m_pTreeWidget->topLevelItem(i)->isSelected()) + { + ActionData * a = ((ActionEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i))->actionData(); + + KviKvsUserAction::exportToKvs( + szCode, + a->m_szName, + a->m_szScriptCode, + a->m_szVisibleName, + a->m_szDescription, + a->m_szCategory, + a->m_szBigIcon, + a->m_szSmallIcon, + a->m_uFlags, + a->m_szKeySequence + ); + } + } + + if(!KviFileUtils::writeFile(szFile,szCode)) + { + QMessageBox::warning(this,__tr2qs_ctx("Write Failed - KVIrc","editor"),__tr2qs_ctx("Unable to write to the actions file.","editor"),__tr2qs_ctx("OK","editor")); + } +} + +void ActionEditor::deleteActions() +{ + KviPointerList l; + l.setAutoDelete(false); + + for (int i=0;itopLevelItemCount();i++) + { + if(m_pTreeWidget->topLevelItem(i)->isSelected()) + l.append((ActionEditorTreeWidgetItem * )m_pTreeWidget->topLevelItem(i)); + } + + if(l.isEmpty())return; + + //if(QMessageBox::question(this,__tr2qs_ctx("Confirm Deletion","editor"),__tr2qs_ctx("Do you really want to delete the selected actions ?","editor"),__tr2qs_ctx("Yes","editor"),__tr2qs_ctx("No","editor")) != 0) + // return; + + for(ActionEditorTreeWidgetItem * i = l.first();i;i = l.next()) + { + if(m_pSingleActionEditor->actionData() == i->actionData()) + m_pSingleActionEditor->setActionData(0); + delete i; + } +} + + +QString ActionEditor::nameForAutomaticAction(const QString &szTemplate) +{ + QString ret; + QString szT = szTemplate; + szT.replace(" ",""); + szT.replace(".","_"); + + int i = 1; + do { + KviQString::sprintf(ret,"%Q%d",&szT,i); + i++; + } while(actionExists(ret)); + + return ret; +} + +void ActionEditor::newAction() +{ + QString szName = nameForAutomaticAction(__tr2qs_ctx("My Action","editor")); + QString szVis = __tr2qs_ctx("My Action","editor"); + QString szDes = __tr2qs_ctx("Put here a short description of your action","editor"); + + szVis.prepend("$tr(\""); + szVis.append("\")"); + szDes.prepend("$tr(\""); + szDes.append("\")"); + + ActionData * ad = new ActionData(szName, + QString(), + szVis, + szDes, + KviActionManager::categoryGeneric()->name(), + QString(), + QString(), + 0, + QString(), + 0); + + ActionEditorTreeWidgetItem * lvi = new ActionEditorTreeWidgetItem(m_pTreeWidget,ad); + ad->m_pItem = lvi; + m_pTreeWidget->setCurrentItem(lvi); + currentItemChanged(lvi,lvi); +} + +bool ActionEditor::actionExists(const QString &szName) +{ + for (int i=0;itopLevelItemCount();i++) + { + if(((ActionEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i))->actionData()->m_szName == szName)return true; + } + return false; +} + +void ActionEditor::currentItemChanged(QTreeWidgetItem * i,QTreeWidgetItem *) +{ + if(m_pSingleActionEditor->actionData()) + m_pSingleActionEditor->commit(); + + m_pTreeWidget->update(); + + ActionEditorTreeWidgetItem * it = (ActionEditorTreeWidgetItem *)i; + if(!it) + { + m_pSingleActionEditor->setActionData(0); + m_pDeleteActionsButton->setEnabled(false); + m_pExportActionsButton->setEnabled(false); + return; + } + m_pDeleteActionsButton->setEnabled(true); + m_pExportActionsButton->setEnabled(true); + + //if(!it->isSelected())m_pTreeWidget->setSelected(it,true); + + m_pSingleActionEditor->setActionData(it->actionData()); + g_szLastEditedAction = it->actionData()->m_szName; +} + +void ActionEditor::commit() +{ + m_pSingleActionEditor->commit(); + + // the hard part: update the actions without destroying them... + + KviActionManager::instance()->killAllKvsUserActions(); + + for (int i=0;itopLevelItemCount();i++) + { + ActionEditorTreeWidgetItem * it = (ActionEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i); + KviKvsUserAction * a = KviKvsUserAction::createInstance( // msvc workaround + KviActionManager::instance(), + it->actionData()->m_szName, + it->actionData()->m_szScriptCode, + it->actionData()->m_szVisibleName, + it->actionData()->m_szDescription, + it->actionData()->m_szCategory, + it->actionData()->m_szBigIcon, + it->actionData()->m_szSmallIcon, + it->actionData()->m_uFlags, + it->actionData()->m_szKeySequence); + + KviActionManager::instance()->registerAction(a); + } + + KviCustomToolBarManager::instance()->updateVisibleToolBars(); +} + + +ActionEditorWindow::ActionEditorWindow(KviMainWindow * lpFrm) +: KviWindow(KVI_WINDOW_TYPE_SCRIPTEDITOR,lpFrm,"actioneditor",0) +{ + g_pActionEditorWindow = this; + setFixedCaption(__tr2qs_ctx("Action Editor","editor")); + + QGridLayout * g = new QGridLayout(); + + m_pEditor = new ActionEditor(this); + g->addWidget(m_pEditor,0,0,1,4); + + QPushButton * btn = new QPushButton(__tr2qs_ctx("OK","editor"),this); + connect(btn,SIGNAL(clicked()),this,SLOT(okClicked())); + btn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT))); + g->addWidget(btn,1,1); + + btn = new QPushButton(__tr2qs_ctx("Apply","editor"),this); + connect(btn,SIGNAL(clicked()),this,SLOT(applyClicked())); + btn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT))); + g->addWidget(btn,1,2); + + btn = new QPushButton(__tr2qs_ctx("Cancel","editor"),this); + connect(btn,SIGNAL(clicked()),this,SLOT(cancelClicked())); + btn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD))); + g->addWidget(btn,1,3); + + g->setRowStretch(0,1); + g->setColumnStretch(0,1); + setLayout(g); +} + +ActionEditorWindow::~ActionEditorWindow() +{ + g_pActionEditorWindow = 0; +} + +void ActionEditorWindow::okClicked() +{ + m_pEditor->commit(); + close(); +} + +void ActionEditorWindow::applyClicked() +{ + m_pEditor->commit(); +} + +void ActionEditorWindow::cancelClicked() +{ + close(); +} + +QPixmap * ActionEditorWindow::myIconPtr() +{ + return g_pIconManager->getSmallIcon(KVI_SMALLICON_SCRIPTACTION); +} + +void ActionEditorWindow::getConfigGroupName(QString &szName) +{ + szName = "actioneditor"; +} + +void ActionEditorWindow::saveProperties(KviConfigurationFile *cfg) +{ + KviWindow::saveProperties(cfg); + cfg->writeEntry("Splitter",m_pEditor->m_pSplitter->sizes()); +} + +void ActionEditorWindow::loadProperties(KviConfigurationFile *cfg) +{ + int w = width(); + KviWindow::loadProperties(cfg); + QList def; + def.append((w * 25) / 100); + def.append((w * 75) / 100); + m_pEditor->m_pSplitter->setSizes(cfg->readIntListEntry("Splitter",def)); +} diff --git a/src/modules/actioneditor/ActionEditor.h b/src/modules/actioneditor/ActionEditor.h new file mode 100644 index 000000000..ac05ec216 --- /dev/null +++ b/src/modules/actioneditor/ActionEditor.h @@ -0,0 +1,204 @@ +#ifndef _ACTIONEDITOR_H_ +#define _ACTIONEDITOR_H_ +//============================================================================= +// +// File : ActionEditor.h +// Creation date : Tue Dec 29 2004 02:40:55 CEST by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2004-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the linkss of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviWindow.h" +#include + +#include +#include +#include +#include + + +class QLineEdit; +class QComboBox; +class QSimpleRichText; +class QPushButton; +class QSplitter; +class ActionEditorTreeWidgetItem; +class KviScriptEditor; +class ActionEditor; + + +class ActionData +{ +public: + QString m_szName; + QString m_szScriptCode; + QString m_szVisibleName; + QString m_szDescription; + QString m_szCategory; + QString m_szBigIcon; + QString m_szSmallIcon; + QString m_szKeySequence; + unsigned int m_uFlags; + ActionEditorTreeWidgetItem * m_pItem; // ummigarba tanto... +public: + ActionData(const QString &szName, + const QString &szScriptCode, + const QString &szVisibleName, + const QString &szDescription, + const QString &szCategory, + const QString &szBigIcon, + const QString &szSmallIcon, + unsigned int uFlags, + const QString &szKeySequence, + ActionEditorTreeWidgetItem * pItem) + : m_szName(szName), m_szScriptCode(szScriptCode), m_szVisibleName(szVisibleName), + m_szDescription(szDescription), m_szCategory(szCategory), m_szBigIcon(szBigIcon), + m_szSmallIcon(szSmallIcon), m_szKeySequence(szKeySequence), m_uFlags(uFlags), + m_pItem(pItem) + {}; +}; + + +class ActionEditorTreeWidgetItem : public QTreeWidgetItem +{ +public: + ActionEditorTreeWidgetItem(QTreeWidget * v,ActionData * a); + ~ActionEditorTreeWidgetItem(); +protected: + ActionData * m_pActionData; + //QSimpleRichText * m_pText; + QTextDocument * m_pText; + QPixmap * m_pIcon; + QTreeWidget * m_pTreeWidget; + QString m_szKey; +public: + ActionData * actionData(){ return m_pActionData; }; + //void setupForActionData(); +public: + //virtual void paintCell(QPainter * p,const QColorGroup & cg,int column,int width,int align); + //virtual void setup(); + virtual QString key(int,bool) const; +}; + + +class ActionEditorTreeView : public QTreeWidget +{ + Q_OBJECT +public: + ActionEditorTreeView(QWidget * pParent); + ~ActionEditorTreeView(); +protected: + virtual void resizeEvent(QResizeEvent * e); +}; + + +class SingleActionEditor : public QWidget +{ + Q_OBJECT +public: + SingleActionEditor(QWidget * par,ActionEditor * ed); + ~SingleActionEditor(); +protected: + ActionEditor * m_pActionEditor; + ActionData * m_pActionData; + QLineEdit * m_pNameEdit; + QLineEdit * m_pVisibleNameEdit; + QComboBox * m_pCategoryCombo; + KviScriptEditor * m_pScriptEditor; + QLineEdit * m_pKeySequenceEdit; + QLineEdit * m_pDescriptionEdit; + QLineEdit * m_pSmallIconEdit; + QLineEdit * m_pBigIconEdit; + QToolButton * m_pSmallIconButton; + QToolButton * m_pBigIconButton; + QCheckBox * m_pNeedsContextCheck; + QCheckBox * m_pNeedsConnectionCheck; + QCheckBox * m_pEnableAtLoginCheck; + QCheckBox * m_pSpecificWindowsCheck; + QCheckBox * m_pWindowConsoleCheck; + QCheckBox * m_pWindowChannelCheck; + QCheckBox * m_pWindowQueryCheck; + QCheckBox * m_pWindowDccChatCheck; + QCheckBox * m_pConsoleOnlyIfUsersSelectedCheck; + QCheckBox * m_pChannelOnlyIfUsersSelectedCheck; + QCheckBox * m_pQueryOnlyIfUsersSelectedCheck; +public: + ActionData * actionData(){ return m_pActionData; }; + void setActionData(ActionData * d); + void commit(); +protected slots: + void chooseSmallIcon(); + void chooseBigIcon(); + void displaySmallIcon(const QString &szIconId); + void displayBigIcon(const QString &szIconId); + void needsContextCheckToggled(bool); + void needsConnectionCheckToggled(bool); + void specificWindowsCheckToggled(bool); + void channelQueryOrConsoleWindowCheckToggled(bool); +}; + + +class ActionEditor : public QWidget +{ + friend class ActionEditorWindow; + Q_OBJECT +public: + ActionEditor(QWidget * par); + ~ActionEditor(); +protected: + ActionEditorTreeView * m_pTreeWidget; + SingleActionEditor * m_pSingleActionEditor; + QSplitter * m_pSplitter; + QPushButton * m_pNewActionButton; + QPushButton * m_pDeleteActionsButton; + QPushButton * m_pExportActionsButton; +public: + void commit(); + bool actionExists(const QString &szName); +protected: + int selectedCount(); + QString nameForAutomaticAction(const QString &szTemplate); +protected slots: + void currentItemChanged(QTreeWidgetItem * it,QTreeWidgetItem *prev); + void newAction(); + void deleteActions(); + void exportActions(); +}; + + +class ActionEditorWindow : public KviWindow +{ + Q_OBJECT +public: + ActionEditorWindow(KviMainWindow * lpFrm); + ~ActionEditorWindow(); +protected: + ActionEditor * m_pEditor; +protected: + virtual QPixmap * myIconPtr(); + virtual void getConfigGroupName(QString &szName); + virtual void saveProperties(KviConfigurationFile *); + virtual void loadProperties(KviConfigurationFile *); +protected slots: + void cancelClicked(); + void okClicked(); + void applyClicked(); +}; + +#endif //_ACTIONEDITOR_H_ diff --git a/src/modules/actioneditor/CMakeLists.txt b/src/modules/actioneditor/CMakeLists.txt index a3fb5c56c..15efd644d 100644 --- a/src/modules/actioneditor/CMakeLists.txt +++ b/src/modules/actioneditor/CMakeLists.txt @@ -1,11 +1,11 @@ # CMakeLists for src/modules/actioneditor SET(kviactioneditor_MOC_HDRS - actioneditor.h + ActionEditor.h ) SET(kviactioneditor_SRCS - actioneditor.cpp + ActionEditor.cpp libkviactioneditor.cpp ) diff --git a/src/modules/actioneditor/actioneditor.cpp b/src/modules/actioneditor/actioneditor.cpp deleted file mode 100644 index 0d80af6f2..000000000 --- a/src/modules/actioneditor/actioneditor.cpp +++ /dev/null @@ -1,939 +0,0 @@ -//============================================================================= -// -// File : aliaseditor.cpp -// Creation date : Tue 29 Dec 2004 02:45:59 2002 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2004-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the linkss of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= -#include "actioneditor.h" - -#include "KviIconManager.h" -#include "KviOptions.h" -#include "KviLocale.h" -#include "KviImageDialog.h" -#include "KviConfigurationFile.h" -#include "KviFileUtils.h" -#include "KviScriptEditor.h" -#include "kvi_debug.h" -#include "KviApplication.h" -#include "KviQString.h" -#include "KviKvsAliasManager.h" -#include "KviFileDialog.h" -#include "KviActionManager.h" -#include "KviAction.h" -#include "KviKvsUserAction.h" -#include "KviCustomToolBarManager.h" -#include "KviTalVBox.h" -#include -#include "KviTalIconAndRichTextItemDelegate.h" -#include "kvi_fileextensions.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -extern KviActionEditorWindow * g_pActionEditorWindow; - -static QString g_szLastEditedAction; - -#define LVI_ICON_SIZE 32 -#define LVI_BORDER 4 -#define LVI_SPACING 8 -#define LVI_MINIMUM_CELL_WIDTH (LVI_MINIMUM_TEXT_WIDTH + LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING + LVI_BORDER) - -KviActionEditorTreeWidgetItem::KviActionEditorTreeWidgetItem(QTreeWidget * v,KviActionData * a) -: QTreeWidgetItem(v) -{ - m_pActionData = a; - m_pTreeWidget = v; - //setFlags(Qt::ItemIsUserSelectable); - QString t = "" + m_pActionData->m_szName + ""; - t += "
" + m_pActionData->m_szVisibleName + ""; - m_szKey = m_pActionData->m_szName.toUpper(); - setText(0,t); - QPixmap * p = g_pIconManager->getBigIcon(m_pActionData->m_szBigIcon); - if(p)setIcon(0,*p); -} - -KviActionEditorTreeWidgetItem::~KviActionEditorTreeWidgetItem() -{ - delete m_pActionData; -} - - -QString KviActionEditorTreeWidgetItem::key(int,bool) const -{ - return m_szKey; -} - -KviSingleActionEditor::KviSingleActionEditor(QWidget * par,KviActionEditor * ed) -: QWidget(par) -{ - m_pActionEditor = ed; - m_pActionData = 0; - - QGridLayout * g = new QGridLayout(this); - - QLabel * l = new QLabel(__tr2qs_ctx("Name:","editor"),this); - g->addWidget(l,0,0); - m_pNameEdit = new QLineEdit(this); - g->addWidget(m_pNameEdit,0,1); - m_pNameEdit->setToolTip(__tr2qs_ctx("Internal unique name for the action","editor")); - - l = new QLabel(__tr2qs_ctx("Label:","editor"),this); - g->addWidget(l,1,0); - m_pVisibleNameEdit = new QLineEdit(this); - g->addWidget(m_pVisibleNameEdit,1,1); - m_pVisibleNameEdit->setToolTip(__tr2qs_ctx("Visible name for this action.
This string will be displayed to the user so it is a good idea to use $tr() here","editor")); - - - QTabWidget * tw = new QTabWidget(this); - g->addWidget(tw,2,0,1,2); -// g->addMultiCellWidget(tw,2,2,0,1); - - // code tab - QWidget * tab = new QWidget(tw); - QGridLayout * gl = new QGridLayout(tab); - - m_pScriptEditor = KviScriptEditor::createInstance(tab); - gl->addWidget(m_pScriptEditor,0,0); - m_pScriptEditor->setToolTip(__tr2qs_ctx("Action code","editor")); - - tw->addTab(tab,__tr2qs_ctx("Code","editor")); - - // properties tab - tab = new QWidget(tw); - gl = new QGridLayout(tab); - - l = new QLabel(__tr2qs_ctx("Category:","editor"),tab); - gl->addWidget(l,0,0); - m_pCategoryCombo = new QComboBox(tab); - gl->addWidget(m_pCategoryCombo,0,1,1,3); - //gl->addMultiCellWidget(m_pCategoryCombo,0,0,1,3); - m_pCategoryCombo->setToolTip(__tr2qs_ctx("Choose the category that best fits for this action","editor")); - - l = new QLabel(__tr2qs_ctx("Description:","editor"),tab); - gl->addWidget(l,1,0); - m_pDescriptionEdit = new QLineEdit(tab); - gl->addWidget(m_pDescriptionEdit,1,1,1,3); -// gl->addMultiCellWidget(m_pDescriptionEdit,1,1,1,3); - m_pDescriptionEdit->setToolTip(__tr2qs_ctx("Visible short description for this action.
This string will be displayed to the user so it is a good idea to use $tr() here","editor")); - - l = new QLabel(__tr2qs_ctx("Small Icon:","editor"),tab); - gl->addWidget(l,2,0); - m_pSmallIconEdit = new QLineEdit(tab); - gl->addWidget(m_pSmallIconEdit,2,1); - m_pSmallIconButton = new QToolButton(tab); - m_pSmallIconButton->setMinimumSize(QSize(20,20)); - connect(m_pSmallIconButton,SIGNAL(clicked()),this,SLOT(chooseSmallIcon())); - gl->addWidget(m_pSmallIconButton,2,2); - QString s= __tr2qs_ctx("The small icon associated to this action.
" \ - "It will appear at least in the popup menus when this action is inserted.
" \ - "It has to be 16x16 pixels.","editor"); - m_pSmallIconEdit->setToolTip(s); - m_pSmallIconButton->setToolTip(s); - - l = new QLabel(__tr2qs_ctx("Big Icon:","editor"),tab); - gl->addWidget(l,3,0); - m_pBigIconEdit = new QLineEdit(tab); - gl->addWidget(m_pBigIconEdit,3,1); - m_pBigIconButton = new QToolButton(tab); - m_pBigIconButton->setMinimumSize(QSize(48,48)); - m_pBigIconButton->setIconSize(QSize(32,32)); - connect(m_pBigIconButton,SIGNAL(clicked()),this,SLOT(chooseBigIcon())); - gl->addWidget(m_pBigIconButton,3,2,2,2); -// gl->addMultiCellWidget(m_pBigIconButton,3,4,2,3); - s = __tr2qs_ctx("The big icon associated to this action.
" \ - "It will appear at least in the toolbar buttons when this action is inserted.
" \ - "It has to be 32x32 pixels.","editor"); - m_pBigIconEdit->setToolTip(s); - m_pBigIconButton->setToolTip(s); - - l = new QLabel(__tr2qs_ctx("Key Sequence:","editor"),tab); - gl->addWidget(l,4,0,2,1); -// gl->addMultiCellWidget(l,4,5,0,0); - m_pKeySequenceEdit = new QLineEdit(tab); - gl->addWidget(m_pKeySequenceEdit,4,1,2,1); -// gl->addMultiCellWidget(m_pKeySequenceEdit,4,5,1,1); - m_pKeySequenceEdit->setToolTip(__tr2qs_ctx("Optional keyboard sequence that will activate this action.
" \ - "The sequence has to be expressed as a string of up to four key codes separated by commas " \ - "eventually combined with the modifiers \"Ctrl\",\"Shift\",\"Alt\" and \"Meta\".
" \ - "Examples of such sequences are \"Ctrl+X\", \"Ctrl+Alt+Z\", \"Ctrl+X,Ctrl+C\" ...","editor")); - - l = new QLabel(tab); - gl->addWidget(l,6,0,1,4); -// gl->addMultiCellWidget(l,6,6,0,3); - - gl->setColumnStretch(1,1); - gl->setRowStretch(6,1); - - - tw->addTab(tab,__tr2qs_ctx("Properties","editor")); - - - - // flags tab - tab = new QWidget(tw); - gl = new QGridLayout(tab); - - - m_pNeedsContextCheck = new QCheckBox(__tr2qs_ctx("Needs IRC Context","editor"),tab); - connect(m_pNeedsContextCheck,SIGNAL(toggled(bool)),this,SLOT(needsContextCheckToggled(bool))); - m_pNeedsContextCheck->setToolTip(__tr2qs_ctx("Check this option if this action should be enabled only when " \ - "the active window belongs to an irc context","editor")); - gl->addWidget(m_pNeedsContextCheck,0,0,1,4); - - - l = new QLabel(tab); - l->setMinimumWidth(40); - gl->addWidget(l,1,0); - - m_pNeedsConnectionCheck = new QCheckBox(__tr2qs_ctx("Needs IRC Connection","editor"),tab); - connect(m_pNeedsConnectionCheck,SIGNAL(toggled(bool)),this,SLOT(needsConnectionCheckToggled(bool))); - m_pNeedsConnectionCheck->setToolTip(__tr2qs_ctx("Check this option if this action should be enabled only when " \ - "the active window has an active IRC connection","editor")); - gl->addWidget(m_pNeedsConnectionCheck,1,1,1,3); - - - l = new QLabel(tab); - l->setMinimumWidth(40); - gl->addWidget(l,2,1); - - m_pEnableAtLoginCheck = new QCheckBox(__tr2qs_ctx("Enable at Login","editor"),tab); - m_pEnableAtLoginCheck->setToolTip(__tr2qs_ctx("Check this option if this action should be enabled also during " \ - "the login operations (so when the logical IRC connection hasn't been estabilished yet)","editor")); - gl->addWidget(m_pEnableAtLoginCheck,2,2,1,2); - - m_pSpecificWindowsCheck = new QCheckBox(__tr2qs_ctx("Enable Only in Specified Windows","editor"),tab); - connect(m_pSpecificWindowsCheck,SIGNAL(toggled(bool)),this,SLOT(specificWindowsCheckToggled(bool))); - m_pSpecificWindowsCheck->setToolTip(__tr2qs_ctx("Check this option if this action should be enabled only when " \ - "the active window is of a specified type","editor")); - gl->addWidget(m_pSpecificWindowsCheck,3,0,1,4); - - - m_pWindowConsoleCheck = new QCheckBox(__tr2qs_ctx("Enable in Console Windows","editor"),tab); - m_pWindowConsoleCheck->setToolTip(__tr2qs_ctx("Check this option if this action should be enabled only when " \ - "the active window is a console","editor")); - connect(m_pWindowConsoleCheck,SIGNAL(toggled(bool)),this,SLOT(channelQueryOrConsoleWindowCheckToggled(bool))); - gl->addWidget(m_pWindowConsoleCheck,4,1,1,3); - - m_pConsoleOnlyIfUsersSelectedCheck = new QCheckBox(__tr2qs_ctx("Only If There Are Selected Users","editor"),tab); - m_pConsoleOnlyIfUsersSelectedCheck->setToolTip(__tr2qs_ctx("This will enable the action only if there are " \ - "selected users in the active window","editor")); - gl->addWidget(m_pConsoleOnlyIfUsersSelectedCheck,5,2,1,2); - - m_pWindowChannelCheck = new QCheckBox(__tr2qs_ctx("Enable in Channel Windows","editor"),tab); - m_pWindowChannelCheck->setToolTip(__tr2qs_ctx("Check this option if this action should be enabled only when " \ - "the active window is a channel","editor")); - connect(m_pWindowChannelCheck,SIGNAL(toggled(bool)),this,SLOT(channelQueryOrConsoleWindowCheckToggled(bool))); - gl->addWidget(m_pWindowChannelCheck,6,1,1,3); - - m_pChannelOnlyIfUsersSelectedCheck = new QCheckBox(__tr2qs_ctx("Only If There Are Selected Users","editor"),tab); - m_pChannelOnlyIfUsersSelectedCheck->setToolTip(__tr2qs_ctx("This will enable the action only if there are " \ - "selected users in the active window","editor")); - gl->addWidget(m_pChannelOnlyIfUsersSelectedCheck,7,2,1,2); - - m_pWindowQueryCheck = new QCheckBox(__tr2qs_ctx("Enable in Query Windows","editor"),tab); - m_pWindowQueryCheck->setToolTip(__tr2qs_ctx("Check this option if this action should be enabled only when " \ - "the active window is a query","editor")); - connect(m_pWindowQueryCheck,SIGNAL(toggled(bool)),this,SLOT(channelQueryOrConsoleWindowCheckToggled(bool))); - gl->addWidget(m_pWindowQueryCheck,8,1,1,3); - - m_pQueryOnlyIfUsersSelectedCheck = new QCheckBox(__tr2qs_ctx("Only If There Are Selected Users","editor"),tab); - m_pQueryOnlyIfUsersSelectedCheck->setToolTip(__tr2qs_ctx("This will enable the action only if there are " \ - "selected users in the active window","editor")); - gl->addWidget(m_pQueryOnlyIfUsersSelectedCheck,9,2,1,2); - - m_pWindowDccChatCheck = new QCheckBox(__tr2qs_ctx("Enable in DCC Chat Windows","editor"),tab); - m_pWindowDccChatCheck->setToolTip(__tr2qs_ctx("Check this option if this action should be enabled only when " \ - "the active window is a dcc chat","editor")); - gl->addWidget(m_pWindowDccChatCheck,10,1,1,2); - - l = new QLabel(tab); - gl->addWidget(l,11,0,1,4); - gl->setColumnStretch(3,1); - gl->setRowStretch(11,1); - - tw->addTab(tab,__tr2qs_ctx("Flags","editor")); - tw->setCurrentIndex(0); - - g->setRowStretch(2,1); - g->setColumnStretch(1,1); - - KviPointerHashTableIterator it(*(KviActionManager::instance()->categories())); - while(KviActionCategory * ac = it.current()) - { - m_pCategoryCombo->addItem(ac->visibleName() + " (" + ac->name() + ")"); - ++it; - } -} - -KviSingleActionEditor::~KviSingleActionEditor() -{ -} - -void KviSingleActionEditor::channelQueryOrConsoleWindowCheckToggled(bool) -{ - m_pChannelOnlyIfUsersSelectedCheck->setEnabled(m_pWindowChannelCheck->isChecked()); - m_pChannelOnlyIfUsersSelectedCheck->setChecked(false); - m_pQueryOnlyIfUsersSelectedCheck->setEnabled(m_pWindowQueryCheck->isChecked()); - m_pQueryOnlyIfUsersSelectedCheck->setChecked(false); - m_pConsoleOnlyIfUsersSelectedCheck->setEnabled(m_pWindowConsoleCheck->isChecked()); - m_pConsoleOnlyIfUsersSelectedCheck->setChecked(false); -} - -void KviSingleActionEditor::needsContextCheckToggled(bool) -{ - m_pEnableAtLoginCheck->setChecked(false); - m_pEnableAtLoginCheck->setEnabled(false); - m_pNeedsConnectionCheck->setChecked(false); - m_pNeedsConnectionCheck->setEnabled(m_pNeedsContextCheck->isChecked()); -} - -void KviSingleActionEditor::needsConnectionCheckToggled(bool) -{ - m_pEnableAtLoginCheck->setChecked(false); - m_pEnableAtLoginCheck->setEnabled(m_pNeedsConnectionCheck->isChecked()); -} - -void KviSingleActionEditor::specificWindowsCheckToggled(bool) -{ - m_pWindowConsoleCheck->setChecked(false); - m_pWindowChannelCheck->setChecked(false); - m_pWindowQueryCheck->setChecked(false); - m_pWindowDccChatCheck->setChecked(false); - m_pQueryOnlyIfUsersSelectedCheck->setChecked(false); - m_pChannelOnlyIfUsersSelectedCheck->setChecked(false); - m_pConsoleOnlyIfUsersSelectedCheck->setChecked(false); - m_pQueryOnlyIfUsersSelectedCheck->setEnabled(false); - m_pChannelOnlyIfUsersSelectedCheck->setEnabled(false); - m_pConsoleOnlyIfUsersSelectedCheck->setEnabled(false); - bool b = m_pSpecificWindowsCheck->isChecked(); - m_pWindowConsoleCheck->setEnabled(b); - m_pWindowChannelCheck->setEnabled(b); - m_pWindowQueryCheck->setEnabled(b); - m_pWindowDccChatCheck->setEnabled(b); -} - -void KviSingleActionEditor::displaySmallIcon(const QString &szIconId) -{ - QPixmap * pix = g_pIconManager->getImage(szIconId); - - if(pix) - { - m_pSmallIconEdit->setText(szIconId); - m_pSmallIconButton->setIcon(QIcon(*pix)); - } else { - m_pSmallIconEdit->setText(QString()); - m_pSmallIconButton->setIcon(QIcon()); - } - -} - -void KviSingleActionEditor::displayBigIcon(const QString &szIconId) -{ - QPixmap * pix = g_pIconManager->getImage(szIconId); - - if(pix) - { - m_pBigIconEdit->setText(szIconId); - m_pBigIconButton->setIcon(QIcon(*pix)); - } else { - m_pBigIconEdit->setText(QString()); - m_pBigIconButton->setIcon(QIcon()); - } -} - -void KviSingleActionEditor::chooseSmallIcon() -{ - if(!m_pActionData)return; - KviImageDialog * d = new KviImageDialog(this); - int ret = d->exec(); - QString s = d->selectedImage(); - delete d; - if(ret != QDialog::Accepted) - return; - - displaySmallIcon(s); -} - -void KviSingleActionEditor::chooseBigIcon() -{ - if(!m_pActionData)return; - KviImageDialog * d = new KviImageDialog(this,QString(),KID_TYPE_ALL,KID_TYPE_FULL_PATH); - int ret = d->exec(); - QString s = d->selectedImage(); - delete d; - if(ret != QDialog::Accepted) - return; - - displayBigIcon(s); -} - -void KviSingleActionEditor::setActionData(KviActionData * d) -{ - m_pActionData = d; - - if(d) - { - unsigned int uOldFlags = d->m_uFlags; - d->m_uFlags = KviAction::validateFlags(d->m_uFlags); - if(d->m_uFlags != uOldFlags) - qDebug("invalid action flags in KviSingleActionEditor::setActionData(): %d fixed to %d",uOldFlags,d->m_uFlags); - - m_pNameEdit->setText(d->m_szName); - m_pNameEdit->setEnabled(true); - m_pVisibleNameEdit->setText(d->m_szVisibleName); - m_pVisibleNameEdit->setEnabled(true); - m_pCategoryCombo->setEnabled(true); - int i; - for(i=0;icount();i++) - { - QString t = m_pCategoryCombo->itemText(i); - int idx = t.lastIndexOf('('); - QString r = t.right(t.length() - (idx + 1)); - QString r2 = r.left(r.length() - 1); - r2.trimmed(); - if(r2 == d->m_szCategory) - { - m_pCategoryCombo->setCurrentIndex(i); - break; - } - } - if(i == m_pCategoryCombo->count()) - { - m_pCategoryCombo->setCurrentIndex(0); - } - m_pScriptEditor->setText(d->m_szScriptCode); - m_pScriptEditor->setEnabled(true); - m_pKeySequenceEdit->setText(d->m_szKeySequence); - m_pKeySequenceEdit->setEnabled(true); - m_pDescriptionEdit->setText(d->m_szDescription); - m_pDescriptionEdit->setEnabled(true); - m_pSmallIconEdit->setEnabled(true); - m_pBigIconEdit->setEnabled(true); - displaySmallIcon(d->m_szSmallIcon); - displayBigIcon(d->m_szBigIcon); - m_pSmallIconButton->setEnabled(true); - m_pBigIconButton->setEnabled(true); - m_pNeedsContextCheck->setEnabled(true); - bool b = (d->m_uFlags & KviAction::NeedsContext) || (d->m_uFlags & KviAction::NeedsConnection); - m_pNeedsContextCheck->setChecked(b); - - m_pNeedsConnectionCheck->setEnabled(b); - b = (d->m_uFlags & KviAction::NeedsContext) && (d->m_uFlags & KviAction::NeedsConnection); - m_pNeedsConnectionCheck->setChecked(b); - - m_pEnableAtLoginCheck->setEnabled(b); - m_pEnableAtLoginCheck->setChecked(b && (d->m_uFlags & KviAction::EnableAtLogin)); - - m_pSpecificWindowsCheck->setEnabled(true); - b = d->m_uFlags & KviAction::InternalWindowMask; - m_pSpecificWindowsCheck->setChecked(b); - - m_pWindowConsoleCheck->setEnabled(b); - m_pWindowChannelCheck->setEnabled(b); - m_pWindowQueryCheck->setEnabled(b); - m_pWindowDccChatCheck->setEnabled(b); - b = d->m_uFlags & KviAction::WindowConsole; - m_pWindowConsoleCheck->setChecked(b); - m_pConsoleOnlyIfUsersSelectedCheck->setEnabled(b); - m_pConsoleOnlyIfUsersSelectedCheck->setChecked(b && (d->m_uFlags & KviAction::WindowOnlyIfUsersSelected)); - b = d->m_uFlags & KviAction::WindowChannel; - m_pWindowChannelCheck->setChecked(b); - m_pChannelOnlyIfUsersSelectedCheck->setEnabled(b); - m_pChannelOnlyIfUsersSelectedCheck->setChecked(b && (d->m_uFlags & KviAction::WindowOnlyIfUsersSelected)); - b = d->m_uFlags & KviAction::WindowQuery; - m_pWindowQueryCheck->setChecked(b); - m_pQueryOnlyIfUsersSelectedCheck->setEnabled(b); - m_pQueryOnlyIfUsersSelectedCheck->setChecked(b && (d->m_uFlags & KviAction::WindowOnlyIfUsersSelected)); - m_pWindowDccChatCheck->setChecked(d->m_uFlags & KviAction::WindowDccChat); - } else { - m_pNameEdit->setText(""); - m_pNameEdit->setEnabled(false); - m_pVisibleNameEdit->setText(""); - m_pVisibleNameEdit->setEnabled(false); - m_pCategoryCombo->setEnabled(false); - m_pScriptEditor->setText(""); - m_pScriptEditor->setEnabled(false); - m_pKeySequenceEdit->setText(""); - m_pKeySequenceEdit->setEnabled(false); - m_pDescriptionEdit->setText(""); - m_pDescriptionEdit->setEnabled(false); - m_pSmallIconEdit->setText(""); - m_pSmallIconEdit->setEnabled(false); - m_pBigIconEdit->setText(""); - m_pBigIconEdit->setEnabled(false); - m_pSmallIconButton->setIcon(QIcon()); - m_pSmallIconButton->setEnabled(false); - m_pBigIconButton->setIcon(QPixmap()); - m_pBigIconButton->setEnabled(false); - m_pNeedsContextCheck->setChecked(false); - m_pNeedsContextCheck->setEnabled(false); - m_pNeedsConnectionCheck->setChecked(false); - m_pNeedsConnectionCheck->setEnabled(false); - m_pEnableAtLoginCheck->setChecked(false); - m_pEnableAtLoginCheck->setEnabled(false); - m_pWindowConsoleCheck->setChecked(false); - m_pWindowConsoleCheck->setEnabled(false); - m_pWindowChannelCheck->setChecked(false); - m_pWindowChannelCheck->setEnabled(false); - m_pWindowQueryCheck->setChecked(false); - m_pWindowQueryCheck->setEnabled(false); - m_pWindowDccChatCheck->setChecked(false); - m_pWindowDccChatCheck->setEnabled(false); - m_pSpecificWindowsCheck->setChecked(false); - m_pSpecificWindowsCheck->setEnabled(false); - m_pQueryOnlyIfUsersSelectedCheck->setChecked(false); - m_pChannelOnlyIfUsersSelectedCheck->setChecked(false); - m_pConsoleOnlyIfUsersSelectedCheck->setChecked(false); - m_pQueryOnlyIfUsersSelectedCheck->setEnabled(false); - m_pChannelOnlyIfUsersSelectedCheck->setEnabled(false); - m_pConsoleOnlyIfUsersSelectedCheck->setEnabled(false); - } -} - -void KviSingleActionEditor::commit() -{ - if(!m_pActionData)return; - - QString tmp = m_pNameEdit->text(); - if(tmp != m_pActionData->m_szName) - { - int idx = 1; - while(KviActionManager::instance()->coreActionExists(tmp) || m_pActionEditor->actionExists(tmp)) - { - QString tmp2; - tmp2.setNum(idx); - tmp = m_pNameEdit->text(); - tmp.append(tmp2); - idx++; - } - } - - m_pActionData->m_szName = tmp; - m_pScriptEditor->getText(m_pActionData->m_szScriptCode); - m_pActionData->m_szVisibleName = m_pVisibleNameEdit->text(); - m_pActionData->m_szDescription = m_pDescriptionEdit->text(); - m_pActionData->m_szBigIcon = m_pBigIconEdit->text(); - m_pActionData->m_szSmallIcon = m_pSmallIconEdit->text(); - m_pActionData->m_szKeySequence = m_pKeySequenceEdit->text(); - QString szCat = m_pCategoryCombo->currentText(); - int idx = szCat.lastIndexOf(')'); - if(idx != -1)m_pActionData->m_szCategory = szCat.left(idx); - else m_pActionData->m_szCategory = szCat; - idx = m_pActionData->m_szCategory.lastIndexOf('('); - if(idx != -1)m_pActionData->m_szCategory.remove(0,idx+1); - m_pActionData->m_uFlags = 0; - if(m_pNeedsContextCheck->isChecked()) - { - m_pActionData->m_uFlags |= KviAction::NeedsContext; - if(m_pNeedsConnectionCheck->isChecked()) - { - m_pActionData->m_uFlags |= KviAction::NeedsConnection; - if(m_pEnableAtLoginCheck->isChecked())m_pActionData->m_uFlags |= KviAction::EnableAtLogin; - } - - } - if(m_pSpecificWindowsCheck->isChecked()) - { - if(m_pWindowConsoleCheck->isChecked())m_pActionData->m_uFlags |= KviAction::WindowConsole; - if(m_pWindowChannelCheck->isChecked())m_pActionData->m_uFlags |= KviAction::WindowChannel; - if(m_pWindowQueryCheck->isChecked())m_pActionData->m_uFlags |= KviAction::WindowQuery; - if(m_pWindowDccChatCheck->isChecked())m_pActionData->m_uFlags |= KviAction::WindowDccChat; - if(m_pActionData->m_uFlags & KviAction::InternalWindowMask) - { - if(m_pConsoleOnlyIfUsersSelectedCheck->isChecked() || - m_pChannelOnlyIfUsersSelectedCheck->isChecked() || - m_pQueryOnlyIfUsersSelectedCheck->isChecked()) - { - m_pActionData->m_uFlags |= KviAction::WindowOnlyIfUsersSelected; - } - } - } - - unsigned int uOldFlags = m_pActionData->m_uFlags; - m_pActionData->m_uFlags = KviAction::validateFlags(m_pActionData->m_uFlags); - if(m_pActionData->m_uFlags != uOldFlags) - qDebug("invalid action flags in KviSingleActionEditor::commit(): %d fixed to %d",uOldFlags,m_pActionData->m_uFlags); -} - - -KviActionEditorTreeView::KviActionEditorTreeView(QWidget * pParent) -: QTreeWidget(pParent) -{ - setColumnCount (1); - setHeaderLabel(__tr2qs_ctx("Action","editor")); - setSelectionMode(QAbstractItemView::ExtendedSelection); - setSortingEnabled(true); - int iWidth = viewport()->width(); - if(iWidth < LVI_MINIMUM_CELL_WIDTH)iWidth = LVI_MINIMUM_CELL_WIDTH; - setRootIsDecorated(false); - setColumnWidth(0,iWidth); - -} - -KviActionEditorTreeView::~KviActionEditorTreeView() -{ -} - -void KviActionEditorTreeView::resizeEvent(QResizeEvent * e) -{ - QTreeWidget::resizeEvent(e); - int iWidth = viewport()->width(); - if(iWidth < LVI_MINIMUM_CELL_WIDTH)iWidth = LVI_MINIMUM_CELL_WIDTH; - setColumnWidth(0,iWidth); -} - - -KviActionEditor::KviActionEditor(QWidget * par) -: QWidget(par) -{ - - QGridLayout * l = new QGridLayout(this); - m_pSplitter = new QSplitter(Qt::Horizontal,this); - m_pSplitter->setChildrenCollapsible(false); - l->addWidget(m_pSplitter,0,0); - - - KviTalVBox * box = new KviTalVBox(m_pSplitter); - m_pTreeWidget = new KviActionEditorTreeView(box); - KviTalIconAndRichTextItemDelegate *itemDelegate=new KviTalIconAndRichTextItemDelegate(m_pTreeWidget); - m_pTreeWidget->setItemDelegate(itemDelegate); - //m_pTreeWidget->setShowSortIndicator(true); - m_pTreeWidget->setFocusPolicy(Qt::StrongFocus); - connect(m_pTreeWidget,SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),this,SLOT(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *))); - - m_pNewActionButton = new QPushButton(__tr2qs_ctx("New Action","editor"),box); - connect(m_pNewActionButton,SIGNAL(clicked()),this,SLOT(newAction())); - - m_pDeleteActionsButton = new QPushButton(__tr2qs_ctx("Delete Actions","editor"),box); - connect(m_pDeleteActionsButton,SIGNAL(clicked()),this,SLOT(deleteActions())); - - m_pExportActionsButton = new QPushButton(__tr2qs_ctx("Export Actions...","editor"),box); - connect(m_pExportActionsButton,SIGNAL(clicked()),this,SLOT(exportActions())); - - box->setSpacing(1); - - m_pSingleActionEditor = new KviSingleActionEditor(m_pSplitter,this); - - KviActionEditorTreeWidgetItem * last = 0; - KviActionEditorTreeWidgetItem * first = 0; - - KviPointerHashTableIterator it(*(KviActionManager::instance()->actions())); - while(KviAction * a = it.current()) - { - if(a->isKviUserActionNeverOverrideThis()) - { - KviActionData * ad = new KviActionData( - a->name(), - ((KviKvsUserAction *)a)->scriptCode(), - ((KviKvsUserAction *)a)->visibleNameCode(), - ((KviKvsUserAction *)a)->descriptionCode(), - a->category() ? a->category()->name() : KviActionManager::categoryGeneric()->name(), - a->bigIconId(), - a->smallIconId(), - a->flags(), - a->keySequence(), - 0 - ); - KviActionEditorTreeWidgetItem * lvi = new KviActionEditorTreeWidgetItem(m_pTreeWidget,ad); - ad->m_pItem = lvi; - if(ad->m_szName == g_szLastEditedAction) - last = lvi; - if(!first) - first = lvi; - } - ++it; - } - - if(!last)last = first; // try to sleect the first one then - - if(last) - { - m_pTreeWidget->setCurrentItem(last); - currentItemChanged(last,last); - } else { - currentItemChanged(0,0); - } - -} - -KviActionEditor::~KviActionEditor() -{ -} - -void KviActionEditor::exportActions() -{ - QString szName = QDir::homePath(); - if(!szName.endsWith(QString(KVI_PATH_SEPARATOR)))szName += KVI_PATH_SEPARATOR; - szName += "myactions.kvs"; - - QString szFile; - - if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs_ctx("Choose a Filename - KVIrc","editor"),szName,KVI_FILTER_SCRIPT,true,true,true))return; - - QString szCode; - - for (int i=0;itopLevelItemCount();i++) - { - if(m_pTreeWidget->topLevelItem(i)->isSelected()) - { - KviActionData * a = ((KviActionEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i))->actionData(); - - KviKvsUserAction::exportToKvs( - szCode, - a->m_szName, - a->m_szScriptCode, - a->m_szVisibleName, - a->m_szDescription, - a->m_szCategory, - a->m_szBigIcon, - a->m_szSmallIcon, - a->m_uFlags, - a->m_szKeySequence - ); - } - } - - if(!KviFileUtils::writeFile(szFile,szCode)) - { - QMessageBox::warning(this,__tr2qs_ctx("Write Failed - KVIrc","editor"),__tr2qs_ctx("Unable to write to the actions file.","editor"),__tr2qs_ctx("OK","editor")); - } -} - -void KviActionEditor::deleteActions() -{ - KviPointerList l; - l.setAutoDelete(false); - - for (int i=0;itopLevelItemCount();i++) - { - if(m_pTreeWidget->topLevelItem(i)->isSelected()) - l.append((KviActionEditorTreeWidgetItem * )m_pTreeWidget->topLevelItem(i)); - } - - if(l.isEmpty())return; - - //if(QMessageBox::question(this,__tr2qs_ctx("Confirm Deletion","editor"),__tr2qs_ctx("Do you really want to delete the selected actions ?","editor"),__tr2qs_ctx("Yes","editor"),__tr2qs_ctx("No","editor")) != 0) - // return; - - for(KviActionEditorTreeWidgetItem * i = l.first();i;i = l.next()) - { - if(m_pSingleActionEditor->actionData() == i->actionData()) - m_pSingleActionEditor->setActionData(0); - delete i; - } -} - - -QString KviActionEditor::nameForAutomaticAction(const QString &szTemplate) -{ - QString ret; - QString szT = szTemplate; - szT.replace(" ",""); - szT.replace(".","_"); - - int i = 1; - do { - KviQString::sprintf(ret,"%Q%d",&szT,i); - i++; - } while(actionExists(ret)); - - return ret; -} - -void KviActionEditor::newAction() -{ - QString szName = nameForAutomaticAction(__tr2qs_ctx("My Action","editor")); - QString szVis = __tr2qs_ctx("My Action","editor"); - QString szDes = __tr2qs_ctx("Put here a short description of your action","editor"); - - szVis.prepend("$tr(\""); - szVis.append("\")"); - szDes.prepend("$tr(\""); - szDes.append("\")"); - - KviActionData * ad = new KviActionData(szName, - QString(), - szVis, - szDes, - KviActionManager::categoryGeneric()->name(), - QString(), - QString(), - 0, - QString(), - 0); - - KviActionEditorTreeWidgetItem * lvi = new KviActionEditorTreeWidgetItem(m_pTreeWidget,ad); - ad->m_pItem = lvi; - m_pTreeWidget->setCurrentItem(lvi); - currentItemChanged(lvi,lvi); -} - -bool KviActionEditor::actionExists(const QString &szName) -{ - for (int i=0;itopLevelItemCount();i++) - { - if(((KviActionEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i))->actionData()->m_szName == szName)return true; - } - return false; -} - -void KviActionEditor::currentItemChanged(QTreeWidgetItem * i,QTreeWidgetItem *) -{ - if(m_pSingleActionEditor->actionData()) - m_pSingleActionEditor->commit(); - - m_pTreeWidget->update(); - - KviActionEditorTreeWidgetItem * it = (KviActionEditorTreeWidgetItem *)i; - if(!it) - { - m_pSingleActionEditor->setActionData(0); - m_pDeleteActionsButton->setEnabled(false); - m_pExportActionsButton->setEnabled(false); - return; - } - m_pDeleteActionsButton->setEnabled(true); - m_pExportActionsButton->setEnabled(true); - - //if(!it->isSelected())m_pTreeWidget->setSelected(it,true); - - m_pSingleActionEditor->setActionData(it->actionData()); - g_szLastEditedAction = it->actionData()->m_szName; -} - -void KviActionEditor::commit() -{ - m_pSingleActionEditor->commit(); - - // the hard part: update the actions without destroying them... - - KviActionManager::instance()->killAllKvsUserActions(); - - for (int i=0;itopLevelItemCount();i++) - { - KviActionEditorTreeWidgetItem * it = (KviActionEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i); - KviKvsUserAction * a = KviKvsUserAction::createInstance( // msvc workaround - KviActionManager::instance(), - it->actionData()->m_szName, - it->actionData()->m_szScriptCode, - it->actionData()->m_szVisibleName, - it->actionData()->m_szDescription, - it->actionData()->m_szCategory, - it->actionData()->m_szBigIcon, - it->actionData()->m_szSmallIcon, - it->actionData()->m_uFlags, - it->actionData()->m_szKeySequence); - - KviActionManager::instance()->registerAction(a); - } - - KviCustomToolBarManager::instance()->updateVisibleToolBars(); -} - - -KviActionEditorWindow::KviActionEditorWindow(KviMainWindow * lpFrm) -: KviWindow(KVI_WINDOW_TYPE_SCRIPTEDITOR,lpFrm,"actioneditor",0) -{ - g_pActionEditorWindow = this; - setFixedCaption(__tr2qs_ctx("Action Editor","editor")); - - QGridLayout * g = new QGridLayout(); - - m_pEditor = new KviActionEditor(this); - g->addWidget(m_pEditor,0,0,1,4); - - QPushButton * btn = new QPushButton(__tr2qs_ctx("OK","editor"),this); - connect(btn,SIGNAL(clicked()),this,SLOT(okClicked())); - btn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT))); - g->addWidget(btn,1,1); - - btn = new QPushButton(__tr2qs_ctx("Apply","editor"),this); - connect(btn,SIGNAL(clicked()),this,SLOT(applyClicked())); - btn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT))); - g->addWidget(btn,1,2); - - btn = new QPushButton(__tr2qs_ctx("Cancel","editor"),this); - connect(btn,SIGNAL(clicked()),this,SLOT(cancelClicked())); - btn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD))); - g->addWidget(btn,1,3); - - g->setRowStretch(0,1); - g->setColumnStretch(0,1); - setLayout(g); -} - -KviActionEditorWindow::~KviActionEditorWindow() -{ - g_pActionEditorWindow = 0; -} - -void KviActionEditorWindow::okClicked() -{ - m_pEditor->commit(); - close(); -} - -void KviActionEditorWindow::applyClicked() -{ - m_pEditor->commit(); -} - -void KviActionEditorWindow::cancelClicked() -{ - close(); -} - -QPixmap * KviActionEditorWindow::myIconPtr() -{ - return g_pIconManager->getSmallIcon(KVI_SMALLICON_SCRIPTACTION); -} - -void KviActionEditorWindow::getConfigGroupName(QString &szName) -{ - szName = "actioneditor"; -} - -void KviActionEditorWindow::saveProperties(KviConfigurationFile *cfg) -{ - KviWindow::saveProperties(cfg); - cfg->writeEntry("Splitter",m_pEditor->m_pSplitter->sizes()); -} - -void KviActionEditorWindow::loadProperties(KviConfigurationFile *cfg) -{ - int w = width(); - KviWindow::loadProperties(cfg); - QList def; - def.append((w * 25) / 100); - def.append((w * 75) / 100); - m_pEditor->m_pSplitter->setSizes(cfg->readIntListEntry("Splitter",def)); -} diff --git a/src/modules/actioneditor/actioneditor.h b/src/modules/actioneditor/actioneditor.h deleted file mode 100644 index 0de966c1b..000000000 --- a/src/modules/actioneditor/actioneditor.h +++ /dev/null @@ -1,204 +0,0 @@ -#ifndef _ACTIONEDITOR_H_ -#define _ACTIONEDITOR_H_ -//============================================================================= -// -// File : actioneditor.h -// Creation date : Tue Dec 29 2004 02:40:55 CEST by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2004-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the linkss of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "KviWindow.h" -#include - -#include -#include -#include -#include - - -class QLineEdit; -class QComboBox; -class QSimpleRichText; -class QPushButton; -class QSplitter; -class KviActionEditorTreeWidgetItem; -class KviScriptEditor; -class KviActionEditor; - - -class KviActionData -{ -public: - QString m_szName; - QString m_szScriptCode; - QString m_szVisibleName; - QString m_szDescription; - QString m_szCategory; - QString m_szBigIcon; - QString m_szSmallIcon; - QString m_szKeySequence; - unsigned int m_uFlags; - KviActionEditorTreeWidgetItem * m_pItem; // ummigarba tanto... -public: - KviActionData(const QString &szName, - const QString &szScriptCode, - const QString &szVisibleName, - const QString &szDescription, - const QString &szCategory, - const QString &szBigIcon, - const QString &szSmallIcon, - unsigned int uFlags, - const QString &szKeySequence, - KviActionEditorTreeWidgetItem * pItem) - : m_szName(szName), m_szScriptCode(szScriptCode), m_szVisibleName(szVisibleName), - m_szDescription(szDescription), m_szCategory(szCategory), m_szBigIcon(szBigIcon), - m_szSmallIcon(szSmallIcon), m_szKeySequence(szKeySequence), m_uFlags(uFlags), - m_pItem(pItem) - {}; -}; - - -class KviActionEditorTreeWidgetItem : public QTreeWidgetItem -{ -public: - KviActionEditorTreeWidgetItem(QTreeWidget * v,KviActionData * a); - ~KviActionEditorTreeWidgetItem(); -protected: - KviActionData * m_pActionData; - //QSimpleRichText * m_pText; - QTextDocument * m_pText; - QPixmap * m_pIcon; - QTreeWidget * m_pTreeWidget; - QString m_szKey; -public: - KviActionData * actionData(){ return m_pActionData; }; - //void setupForActionData(); -public: - //virtual void paintCell(QPainter * p,const QColorGroup & cg,int column,int width,int align); - //virtual void setup(); - virtual QString key(int,bool) const; -}; - - -class KviActionEditorTreeView : public QTreeWidget -{ - Q_OBJECT -public: - KviActionEditorTreeView(QWidget * pParent); - ~KviActionEditorTreeView(); -protected: - virtual void resizeEvent(QResizeEvent * e); -}; - - -class KviSingleActionEditor : public QWidget -{ - Q_OBJECT -public: - KviSingleActionEditor(QWidget * par,KviActionEditor * ed); - ~KviSingleActionEditor(); -protected: - KviActionEditor * m_pActionEditor; - KviActionData * m_pActionData; - QLineEdit * m_pNameEdit; - QLineEdit * m_pVisibleNameEdit; - QComboBox * m_pCategoryCombo; - KviScriptEditor * m_pScriptEditor; - QLineEdit * m_pKeySequenceEdit; - QLineEdit * m_pDescriptionEdit; - QLineEdit * m_pSmallIconEdit; - QLineEdit * m_pBigIconEdit; - QToolButton * m_pSmallIconButton; - QToolButton * m_pBigIconButton; - QCheckBox * m_pNeedsContextCheck; - QCheckBox * m_pNeedsConnectionCheck; - QCheckBox * m_pEnableAtLoginCheck; - QCheckBox * m_pSpecificWindowsCheck; - QCheckBox * m_pWindowConsoleCheck; - QCheckBox * m_pWindowChannelCheck; - QCheckBox * m_pWindowQueryCheck; - QCheckBox * m_pWindowDccChatCheck; - QCheckBox * m_pConsoleOnlyIfUsersSelectedCheck; - QCheckBox * m_pChannelOnlyIfUsersSelectedCheck; - QCheckBox * m_pQueryOnlyIfUsersSelectedCheck; -public: - KviActionData * actionData(){ return m_pActionData; }; - void setActionData(KviActionData * d); - void commit(); -protected slots: - void chooseSmallIcon(); - void chooseBigIcon(); - void displaySmallIcon(const QString &szIconId); - void displayBigIcon(const QString &szIconId); - void needsContextCheckToggled(bool); - void needsConnectionCheckToggled(bool); - void specificWindowsCheckToggled(bool); - void channelQueryOrConsoleWindowCheckToggled(bool); -}; - - -class KviActionEditor : public QWidget -{ - friend class KviActionEditorWindow; - Q_OBJECT -public: - KviActionEditor(QWidget * par); - ~KviActionEditor(); -protected: - KviActionEditorTreeView * m_pTreeWidget; - KviSingleActionEditor * m_pSingleActionEditor; - QSplitter * m_pSplitter; - QPushButton * m_pNewActionButton; - QPushButton * m_pDeleteActionsButton; - QPushButton * m_pExportActionsButton; -public: - void commit(); - bool actionExists(const QString &szName); -protected: - int selectedCount(); - QString nameForAutomaticAction(const QString &szTemplate); -protected slots: - void currentItemChanged(QTreeWidgetItem * it,QTreeWidgetItem *prev); - void newAction(); - void deleteActions(); - void exportActions(); -}; - - -class KviActionEditorWindow : public KviWindow -{ - Q_OBJECT -public: - KviActionEditorWindow(KviMainWindow * lpFrm); - ~KviActionEditorWindow(); -protected: - KviActionEditor * m_pEditor; -protected: - virtual QPixmap * myIconPtr(); - virtual void getConfigGroupName(QString &szName); - virtual void saveProperties(KviConfigurationFile *); - virtual void loadProperties(KviConfigurationFile *); -protected slots: - void cancelClicked(); - void okClicked(); - void applyClicked(); -}; - -#endif //_ACTIONEDITOR_H_ diff --git a/src/modules/actioneditor/libkviactioneditor.cpp b/src/modules/actioneditor/libkviactioneditor.cpp index 748a11217..aab1f7835 100644 --- a/src/modules/actioneditor/libkviactioneditor.cpp +++ b/src/modules/actioneditor/libkviactioneditor.cpp @@ -22,13 +22,13 @@ // //============================================================================= -#include "actioneditor.h" +#include "ActionEditor.h" #include "KviModule.h" #include "KviLocale.h" #include "KviMainWindow.h" -KviActionEditorWindow * g_pActionEditorWindow = 0; +ActionEditorWindow * g_pActionEditorWindow = 0; /* @@ -49,7 +49,7 @@ static bool actioneditor_kvs_cmd_open(KviKvsModuleCommandCall * c) { if(!g_pActionEditorWindow) { - g_pActionEditorWindow = new KviActionEditorWindow(c->window()->frame()); + g_pActionEditorWindow = new ActionEditorWindow(c->window()->frame()); c->window()->frame()->addWindow(g_pActionEditorWindow); } diff --git a/src/modules/addon/AddonFunctions.cpp b/src/modules/addon/AddonFunctions.cpp new file mode 100644 index 000000000..83641d90e --- /dev/null +++ b/src/modules/addon/AddonFunctions.cpp @@ -0,0 +1,272 @@ +//============================================================================= +// +// File : AddonFunctions.cpp +// Creation date : Fri 02 May 2008 17:36:07 by Elvio Basello +// +// This file is part of the KVIrc IRC Client distribution +// Copyright (C) 2008 Elvio Basello +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "AddonFunctions.h" + +#include "KviPackageReader.h" +#include "KviLocale.h" +#include "KviMessageBox.h" +#include "KviApplication.h" +#include "KviHtmlDialog.h" +#include "KviIconManager.h" +#include "KviFileUtils.h" +#include "KviMiscUtils.h" +#include "kvi_sourcesdate.h" +#include "KviMainWindow.h" +#include "KviKvsScript.h" + +#include + +#include + +namespace AddonFunctions +{ + bool notAValidAddonPackage(QString &szError) + { + szError = __tr2qs_ctx("The selected file does not seem to be a valid KVIrc addon package","addon"); + return false; + } + + bool installAddonPackage(const QString &szAddonPackageFileName,QString &szError,QWidget * pDialogParent) + { + KviPointerHashTable * pInfoFields; + QString * pValue; + QString szErr; + QPixmap pix; + QByteArray * pByteArray; + bool bInstall; + KviHtmlDialogData hd; + + const char * check_fields[] = { "Name", "Version", "Author", "Description", "Date", "Application" }; + + // check if it is a valid addon file + KviPackageReader r; + if(!r.readHeader(szAddonPackageFileName)) + { + szErr = r.lastError(); + KviQString::sprintf(szError,__tr2qs_ctx("The selected file does not seem to be a valid KVIrc package: %Q","addon"),&szErr); + return false; + } + + pInfoFields = r.stringInfoFields(); + + pValue = pInfoFields->find("PackageType"); + + if(!pValue) + return notAValidAddonPackage(szError); + + if(!KviQString::equalCI(*pValue,"AddonPack")) + return notAValidAddonPackage(szError); + + pValue = pInfoFields->find("AddonPackVersion"); + + if(!pValue) + return notAValidAddonPackage(szError); + + // make sure the default fields exist + for(int i=0;i<6;i++) + { + pValue = pInfoFields->find(check_fields[i]); + if(!pValue) + return notAValidAddonPackage(szError); + } + + // ok.. it should be really valid at this point + // load its picture + pByteArray = r.binaryInfoFields()->find("Image"); + if(pByteArray) + pix.loadFromData(*pByteArray,0,0); + + if(pix.isNull()) + { + // load the default icon + pix = *(g_pIconManager->getBigIcon(KVI_BIGICON_ADDONS)); + } + + QString szPackageName; + QString szPackageVersion; + QString szPackageAuthor; + QString szPackageDescription; + QString szPackageDate; + QString szAddonPackVersion; + QString szPackageApplication; + + QString szAuthor = __tr2qs_ctx("Author","addon"); + QString szCreatedAt = __tr2qs_ctx("Created at","addon"); + QString szCreatedWith = __tr2qs_ctx("Created with","addon"); + + r.getStringInfoField("Name",szPackageName); + r.getStringInfoField("Version",szPackageVersion); + r.getStringInfoField("Author",szPackageAuthor); + r.getStringInfoField("Description",szPackageDescription); + r.getStringInfoField("Application",szPackageApplication); + r.getStringInfoField("Date",szPackageDate); + r.getStringInfoField("AddonPackVersion",szAddonPackVersion); + + QString szWarnings; + QString szTmp; + + bool bValid = true; + + if(szPackageName.isEmpty() || szPackageVersion.isEmpty() || szAddonPackVersion.isEmpty()) + bValid = false; + + if(KviMiscUtils::compareVersions(szAddonPackVersion,KVI_CURRENT_ADDONS_ENGINE_VERSION) < 0) + bValid = false; + + + if(!bValid) + { + szWarnings += "

"; + szWarnings += __tr2qs_ctx("Warning: The addon might be incompatible with this version of KVIrc","addon"); + szWarnings += "

"; + } + + KviQString::sprintf(hd.szHtmlText, + "" \ + "" \ + "

" \ + "

%Q %Q

" \ + "

" \ + "

" \ + "" \ + "

" \ + "

" \ + "%Q" \ + "

" \ + "

" \ + "%Q: %Q
" \ + "%Q: %Q
" \ + "

" \ + "

" \ + "" \ + "%Q: %Q
" \ + "
" \ + "

" \ + "%Q" \ + "
" \ + "" \ + "", + &szPackageName, + &szPackageVersion, + &szPackageDescription, + &szAuthor, + &szPackageAuthor, + &szCreatedAt, + &szPackageDate, + &szCreatedWith, + &szPackageApplication, + &szWarnings + ); + + hd.addImageResource("addon_dialog_pack_image",pix); + hd.addHtmlResource("addon_dialog_main",hd.szHtmlText); + + QString beginCenter = "
"; + QString endCenter = "
"; + + hd.szCaption = __tr2qs_ctx("Install Addon Pack - KVIrc","addon"); + hd.szUpperLabelText = beginCenter + __tr2qs_ctx("You're about to install the following addon package","addon") + endCenter; + hd.szLowerLabelText = beginCenter + __tr2qs_ctx("Do you want to proceed with the installation ?","addon") + endCenter; + hd.szButton1Text = __tr2qs_ctx("Do Not Install","addon"); + hd.szButton2Text = __tr2qs_ctx("Yes, Proceed","addon"); + hd.iDefaultButton = 2; + hd.iCancelButton = 1; + hd.pixIcon = *(g_pIconManager->getSmallIcon(KVI_SMALLICON_ADDONS)); + hd.iMinimumWidth = 350; + hd.iMinimumHeight = 420; + hd.iFlags = KviHtmlDialogData::ForceMinimumSize; + + bInstall = KviHtmlDialog::display(pDialogParent,&hd) == 2; + + if(!bInstall) + return true; + + // Create a random extraction dir + QString szTmpPath, szUnpackPath; + QString szRandomDir = createRandomDir(); + + g_pApp->getLocalKvircDirectory(szTmpPath,KviApplication::Tmp); + KviQString::ensureLastCharIs(szTmpPath,QChar(KVI_PATH_SEPARATOR_CHAR)); + szUnpackPath = szTmpPath + szRandomDir; + QDir szTmpDir(szUnpackPath); + + // Check for dir existence + while(szTmpDir.exists()) + { + szRandomDir = createRandomDir(); + szUnpackPath = szTmpPath + szRandomDir; + szTmpDir = QDir(szUnpackPath); + } + + // Unpack addon package into the random tmp dir + if(!r.unpack(szAddonPackageFileName,szUnpackPath)) + { + szErr = r.lastError(); + KviQString::sprintf(szError,__tr2qs_ctx("Failed to unpack the selected file: %Q","addon"),&szErr); + return false; + } + + // Now we have all stuff in ~/.config/KVIrc/tmp/$rand + KviQString::escapeKvs(&szUnpackPath, KviQString::EscapeSpace); + if(!KviKvsScript::run(QString::fromAscii("parse %1/install.kvs").arg(szUnpackPath), g_pActiveWindow)) + { + // Parsing the script failed + // However, the user should already be notified via normal script output. + } + + if(!KviFileUtils::deleteDir(szUnpackPath)) + { + // FIXME: Just warn the user and assume success? + szErr = __tr2qs_ctx("One or more files can't be deleted","addon"); + KviQString::sprintf(szError,__tr2qs_ctx("Failed to unpack the selected file: %Q","addon"),&szErr); + return false; + } + + return true; + } + + QString createRandomDir() + { + QString szDirName; + char chars[] = { + 'A','B','C','D','E','F','G','H', + 'I','J','K','L','M','N','O','P', + 'Q','R','S','T','U','V','W','X', + 'Y','Z','a','b','c','d','e','f', + 'g','h','i','j','k','l','m','n', + 'o','p','q','r','s','t','u','v', + 'w','x','y','z','-','_','.' + }; + + // Generate dir name + for(int i=0;i<10;i++) + { + int n = rand() % sizeof(chars); + szDirName.append(chars[n]); + } + + return szDirName; + } +} diff --git a/src/modules/addon/AddonFunctions.h b/src/modules/addon/AddonFunctions.h new file mode 100644 index 000000000..adcc455c2 --- /dev/null +++ b/src/modules/addon/AddonFunctions.h @@ -0,0 +1,42 @@ +#ifndef _ADDONFUNCTIONS_H_ +#define _ADDONFUNCTIONS_H_ +//============================================================================= +// +// File : AddonFunctions.h +// Creation date : Fri 02 May 2008 17:36:07 by Elvio Basello +// +// This file is part of the KVIrc IRC Client distribution +// Copyright (C) 2008 Elvio Basello +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" +#include "KviQString.h" + +#include +#include + +#define KVI_CURRENT_ADDONS_ENGINE_VERSION "2.0.0" + +namespace AddonFunctions +{ + bool notAValidAddonPackage(QString & szError); + bool installAddonPackage(const QString & szAddonPackageFileName, QString & szError, QWidget * pDialogParent = 0); + QString createRandomDir(); +} + +#endif //!_ADDONFUNCTIONS_H_ diff --git a/src/modules/addon/CMakeLists.txt b/src/modules/addon/CMakeLists.txt index f52881251..53ee2e847 100644 --- a/src/modules/addon/CMakeLists.txt +++ b/src/modules/addon/CMakeLists.txt @@ -2,14 +2,14 @@ SET(kviaddon_MOC_HDRS managementdialog.h - packaddondialog.h + PackAddonDialog.h ) SET(kviaddon_SRCS libkviaddon.cpp managementdialog.cpp - packaddondialog.cpp - addonfunctions.cpp + PackAddonDialog.cpp + AddonFunctions.cpp ) # After this call, files will be moc'ed to moc_kvi_*.cpp diff --git a/src/modules/addon/PackAddonDialog.cpp b/src/modules/addon/PackAddonDialog.cpp new file mode 100644 index 000000000..0e36a1654 --- /dev/null +++ b/src/modules/addon/PackAddonDialog.cpp @@ -0,0 +1,664 @@ +//============================================================================ +// +// File : PackAddonDialog.cpp +// Creation date : Sat 03 May 2008 01:40:44 by Elvio Basello +// +// This file is part of the KVIrc IRC Client distribution +// Copyright (C) 2008-2009 Elvio Basello +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================ + +#include "PackAddonDialog.h" +#include "AddonFunctions.h" + +#include "KviLocale.h" +#include "KviFileUtils.h" +#include "KviApplication.h" +#include "KviIconManager.h" +#include "KviPackageWriter.h" +#include "kvi_fileextensions.h" +#include "kvi_sourcesdate.h" +#include "KviOptions.h" + +#include +#include +#include +#include +#include +#include +#include +#include + + +PackAddonDialog::PackAddonDialog(QWidget * pParent) +: QWizard(pParent) +{ + setMinimumSize(400,350); + setObjectName("addon_package_wizard"); + setOption(QWizard::IndependentPages,true); + setWindowTitle(__tr2qs_ctx("Create Addon Package - KVIrc","addon")); + + QPixmap * pSide = g_pIconManager->getBigIcon("kvi_setup_label.png"); + QPixmap * pLogo = g_pIconManager->getBigIcon("kvi_bigicon_addons.png"); + +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + #if (_WIN32_WINNT >= 0x0600) + // We are on a Windows Vista / Seven + // It will fallback to XP if alpha compositing is disabled + setWizardStyle(QWizard::AeroStyle); + #else + // Windows XP + setWizardStyle(QWizard::ModernStyle); + setPixmap(QWizard::WatermarkPixmap,*pSide); + setPixmap(QWizard::LogoPixmap,*pLogo); + #endif +#elif defined(COMPILE_ON_MAC) + setWizardStyle(QWizard::MacStyle); + setPixmap(QWizard::BackgroundPixmap,*pSide); +#else + // All other systems + setWizardStyle(QWizard::ClassicStyle); + setPixmap(QWizard::WatermarkPixmap,*pSide); + setPixmap(QWizard::LogoPixmap,*pLogo); +#endif + + // Add a default property for file selectors + setDefaultProperty("KviFileSelector","tmpFile",SIGNAL(selectionChanged(const QString &))); + + // Welcome page + QWizardPage * pPage = new QWizardPage(this); + QVBoxLayout * pLayout = new QVBoxLayout(pPage); + + pPage->setLayout(pLayout); + pPage->setTitle(__tr2qs_ctx("Welcome","addon")); + + QLabel * pLabel = new QLabel(pPage); + pLabel->setWordWrap(true); + pLabel->setText(__tr2qs_ctx("This procedure allows you to export the selected addon to a single package. It is useful when you want to distribute your addon to the public.","addon")); + pLayout->addWidget(pLabel); + + pLabel = new QLabel(pPage); + pLabel->setWordWrap(true); + QString szText; + szText += __tr2qs_ctx("You will be asked to provide some information like the package name, the version, a description and so on.","addon"); + szText += "

"; + szText += __tr2qs_ctx("Hit the \"Next\" button to begin.","addon"); + pLabel->setText(szText); + pLayout->addWidget(pLabel); + + pPage->setMinimumWidth(350); + + addPage(pPage); + + // Packager information + m_pPackAddonInfoPackageWidget = new PackAddonInfoPackageWidget(this); + addPage(m_pPackAddonInfoPackageWidget); + + // File selection + m_pPackAddonFileSelectionWidget = new PackAddonFileSelectionWidget(this); + addPage(m_pPackAddonFileSelectionWidget); + + // Save selection + m_pPackAddonSaveSelectionWidget = new PackAddonSaveSelectionWidget(this); + addPage(m_pPackAddonSaveSelectionWidget); + + // Summary info + m_pPackAddonSummaryInfoWidget = new PackAddonSummaryInfoWidget(this); + addPage(m_pPackAddonSummaryInfoWidget); + +} + +PackAddonDialog::~PackAddonDialog() +{ +} + +void PackAddonDialog::accept() +{ + if(!packAddon()) + return; + QWizard::accept(); +} + +bool PackAddonDialog::checkDirTree(QString * pszError, QString * pszWarning) +{ + if(pszError) *pszError = ""; + if(pszWarning) *pszWarning = ""; + + QDir addon(m_szDirPath); + if(!addon.exists()) + { + *pszError = __tr2qs_ctx("The selected directory does not exist.","addon"); + return false; + } + + QFileInfo init(m_szDirPath + "/install.kvs"); + if(!init.exists()) + { + *pszError = __tr2qs_ctx("The initialization script (install.kvs) does not exist.","addon"); + return false; + } + + return true; +} + +#if 0 +bool PackAddonDialog::createInstaller(QString * pszError) +{ + if(pszError) + *pszError = ""; + + // Start creating install.kvs: header + QString szTmp; + szTmp += QString("# This file is generated automatically. Do NOT touch unless you know what are you doing\n#\n"); + szTmp += QString("# %1 %2\n# Written by %3\n# %4\n\n").arg(m_szName, m_szVersion, m_szAuthor, m_szDescription); + szTmp += "# Register the script: this must be the first instruction executed\n# since it will abort with an error when a greater version is already installed\n"; + + // install.kvs: addon registration + /* FIXME: re-add in KVIrc 4.1! + * implement a backend with full automatic cleaning for aliases, classes, popups, + * actions, ... via snapshot/diff of kvirc state before/after installing a package + + szTmp += QString("addon.register(\"%1\",\"%2\",\"%1\",\"%3\",\"%4\",\"%5\")\n").arg(m_szName, m_szVersion, m_szDescription, m_szMinVersion, m_szIcon); + szTmp += "{\n"; + szTmp += "\t# This is our uninstall callback: it will be called by KVIrc when addon.uninstall is invoked\n"; + szTmp += QString("\t%1::uninstall::uninstall\n").arg(m_szName); + szTmp += QString("\t%1::uninstall::uninstallfiles\n").arg(m_szName); + szTmp += QString("\t%1::uninstall::uninstallaliases\n").arg(m_szName); + szTmp += "}\n\n"; + szTmp += "# Ok, addon.register succeeded. We can go on with the installation.\n\n"; + */ + + // install.kvs: run path + szTmp += "# Get the path that this script was launched from\n"; + szTmp += "%mypath = $file.extractPath($0)\n\n"; + + // install.kvs: create an instance of the installer class + szTmp += "# The installer will copy our files and generate automatically an uninstallation\n# alias for them\n"; + szTmp += "%installer = $new(installer,0,myaddon)\n\n"; + + // install.kvs: copy files + szTmp += "# Copy files in each subdirectory\n# the pics\n"; + + szTmp += QString("%installer->$copyFiles(\"%mypath/pics\",\"*.png\",$file.localdir(\"pics\"))\n\n"); + szTmp += "# the translations\n"; + szTmp += "%installer->$copyFiles(\"%mypath/locale\",\"*.mo\",$file.localdir(\"locale\"))\n\n"; + + szTmp += "# the documentation\n"; + szTmp += QString("%installer->$copyFiles(\"%mypath/help/\",\"*.html\",$file.localdir(\"help/\"))\n\n"); + + // install.kvs: generate uninstall alias + szTmp += "# Generate the uninstall alias\n"; + szTmp += QString("%installer->$generateUninstallAlias(\"%1::uninstallfiles\")\n\n") \ + .arg(m_szName); + + // kviinstall.kvs: kill the installer class + szTmp += "# Kill the installer helper\n"; + szTmp += "delete %installer\n\n"; + +#if 0 + // install.kvs: fetch the complete script + szTmp += "# Fetch the complete script\n"; + szTmp += "%files[] = $file.ls($file.extractpath($0)/src,f)\n"; + szTmp += QString("%alias = \"alias(%1::uninstall::uninstallaliases){$lf\"\n") \ + .arg(m_szName); + szTmp += "for(%i=0; %i<$length(%files[]); %i++)\n{\n"; + szTmp += "\tinclude $file.extractpath($0)/src/%files[%i]\n"; + szTmp += "\t%flt = $str.left(%files[%i],$($str.len(%files[%i])-4))\n"; + szTmp += "\t%file = $str.replace(%flt,\"_\",\"::\")\n"; + szTmp += "\t%alias .= \"alias(%file){};$lf\"\n}\n"; + szTmp += QString("\t%alias .= \"alias(%1::uninstall::uninstallfiles){};$lf\"\n") \ + .arg(m_szName); + szTmp += QString("\t%alias .= \"alias(%1::uninstall::uninstallaliases){};$lf\"\n") \ + .arg(m_szName); + szTmp += "%alias .= \"}\"\n"; + szTmp += "eval %alias\n\n"; +#endif + + // install.kvs: include initialization file + szTmp += "# Include initialization file\n"; + szTmp += "include \"init.kvs\" %mypath\n\n"; + + // Put the install.kvs in the buffer + QByteArray buffer; + buffer.append(szTmp.toUtf8()); + + // We don't need to check dir existance since it was checked just before + QDir addon(m_szDirPath); + + // Open file for writing + QFile installer(addon.filePath("install.kvs")); + if(!installer.open(QIODevice::WriteOnly)) + { + *pszError = __tr2qs_ctx("Cannot open file for writing.","addon"); + return false; + } + + // Write the buffer to the file descriptor + if(installer.write(buffer) == -1) + { + *pszError = __tr2qs_ctx("Cannot write to the file descriptor.","addon"); + return false; + } + + return true; +} +#endif + + +bool PackAddonDialog::packAddon() +{ + // Get data from registered fields + m_szAuthor = field("packageAuthor").toString(); + m_szName = field("packageName").toString(); + m_szVersion = field("packageVersion").toString(); + m_szDescription = field("packageDescription").toString(); + m_szMinVersion = field("packageMinVersion").toString(); + m_szIcon = field("packageIcon").toString(); + m_szDirPath = field("packageDirPath").toString(); + m_szSavePath = field("packageSavePath").toString(); + + // Check the addon tree + QString szError, szWarning; + + if(!checkDirTree(&szError,&szWarning)) + { + QMessageBox::critical(this, + __tr2qs_ctx("Addon Packaging Error","addon"), + szError,QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton + ); + return false; + } + + if(szWarning != "") + { + QMessageBox::warning(this, + __tr2qs_ctx("Addon Packaging Warning","addon"), + szWarning,QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton + ); + } + + // Raise the files summary dialog + m_pPackAddonSummaryFilesWidget = new PackAddonSummaryFilesWidget(this); + m_pPackAddonSummaryFilesWidget->setPath(m_szDirPath); + if(m_pPackAddonSummaryFilesWidget->exec() == QDialog::Rejected) + { + delete m_pPackAddonSummaryFilesWidget; + return false; + } + + + QString szTmp; + szTmp = QDateTime::currentDateTime().toString(); + + KviPackageWriter pw; + pw.addInfoField("PackageType","AddonPack"); + pw.addInfoField("AddonPackVersion",KVI_CURRENT_ADDONS_ENGINE_VERSION); + pw.addInfoField("Name",m_szName); + pw.addInfoField("Version",m_szVersion); + pw.addInfoField("Author",m_szAuthor); + pw.addInfoField("Description",m_szDescription); + pw.addInfoField("Date",szTmp); + pw.addInfoField("Application","KVIrc " KVI_VERSION "." KVI_SOURCES_DATE); + + QPixmap pix(m_szIcon); + if(!pix.isNull()) + { + QByteArray * pba = new QByteArray(); + QBuffer bufferz(pba,0); + + bufferz.open(QIODevice::WriteOnly); + pix.save(&bufferz,"PNG"); + bufferz.close(); + pw.addInfoField("Image",pba); + } + + QDir dir(m_szDirPath); + QFileInfoList ls = dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::Readable | QDir::NoSymLinks | QDir::NoDotAndDotDot); + + if(ls.isEmpty()) + { + szTmp = __tr2qs_ctx("Packaging failed","addon"); + szTmp += ": "; + szTmp += __tr2qs_ctx("The package file list is empty","addon"); + QMessageBox::critical(this,__tr2qs_ctx("Export Addon - KVIrc","addon"),szTmp,QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton); + return false; + } + + for(QFileInfoList::Iterator it = ls.begin();it != ls.end();++it) + { + const QFileInfo &inf = *it; + + if(inf.isDir()) + { + if(!pw.addDirectory(inf.absoluteFilePath(),QString("%1/").arg(inf.fileName()))) + { + QString szTmp = __tr2qs_ctx("Packaging failed","addon"); + szTmp += ": "; + szTmp += pw.lastError(); + QMessageBox::critical(this,__tr2qs_ctx("Export Addon - KVIrc","addon"),szTmp,QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton); + return false; + } + + continue; + } + + // must be a file + if(!pw.addFile(inf.absoluteFilePath(),inf.fileName())) + { + szTmp = __tr2qs_ctx("Packaging failed","addon"); + szTmp += ": "; + szTmp += pw.lastError(); + QMessageBox::critical(this,__tr2qs_ctx("Export Addon - KVIrc","addon"),szTmp,QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton); + return false; + } + } + + + // Create the addon package + if(m_szSavePath.isEmpty()) + { + m_szSavePath = QDir::homePath(); + KviQString::ensureLastCharIs(m_szSavePath,QChar(KVI_PATH_SEPARATOR_CHAR)); + m_szSavePath += m_szName; + m_szSavePath += "-"; + m_szSavePath += m_szVersion; + m_szSavePath += KVI_FILEEXTENSION_ADDONPACKAGE; + } + + if(!pw.pack(m_szSavePath)) + { + szTmp = __tr2qs_ctx("Packaging failed","addon"); + szTmp += ": "; + szTmp += pw.lastError(); + QMessageBox::critical(this,__tr2qs_ctx("Export Addon - KVIrc","addon"),szTmp,QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton); + return false; + } + + + QMessageBox::information(this,__tr2qs_ctx("Export Addon - KVIrc","addon"),__tr2qs("Package saved successfully in ") + m_szSavePath,QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton); + + return true; +} + + +PackAddonInfoPackageWidget::PackAddonInfoPackageWidget(PackAddonDialog * pParent) +: QWizardPage(pParent) +{ + setObjectName("addon_package_info_page"); + setTitle(__tr2qs_ctx("Package Information","addon")); + setSubTitle(__tr2qs_ctx("Here you need to provide information about you (the packager) and a short description of the package you're creating.","addon")); + + QGridLayout * pLayout = new QGridLayout(this); + + QLabel * pLabel = new QLabel(this); + pLabel->setText(__tr2qs_ctx("Package &Author:","addon")); + pLayout->addWidget(pLabel,0,0); + + m_pPackageAuthorEdit = new QLineEdit(this); + m_pPackageAuthorEdit->setText(__tr2qs_ctx("Your name here","addon")); + pLabel->setBuddy(m_pPackageAuthorEdit); + pLayout->addWidget(m_pPackageAuthorEdit,0,1); + + pLabel = new QLabel(this); + pLabel->setText(__tr2qs_ctx("Package &Name:","addon")); + pLayout->addWidget(pLabel,1,0); + + m_pPackageNameEdit = new QLineEdit(this); + m_pPackageNameEdit->setText(__tr2qs_ctx("No spaces allowed, like MyAddon","addon")); + pLabel->setBuddy(m_pPackageNameEdit); + pLayout->addWidget(m_pPackageNameEdit,1,1); + + pLabel = new QLabel(this); + pLabel->setText(__tr2qs_ctx("Package &Version:","addon")); + pLayout->addWidget(pLabel,2,0); + + m_pPackageVersionEdit = new QLineEdit(this); + m_pPackageVersionEdit->setText(__tr2qs_ctx("Version in the form x.y[.z], like 1.0 or 2.0.3","addon")); + pLabel->setBuddy(m_pPackageVersionEdit); + pLayout->addWidget(m_pPackageVersionEdit,2,1); + + pLabel = new QLabel(this); + pLabel->setText(__tr2qs_ctx("Package &Description:","addon")); + pLayout->addWidget(pLabel,3,0); + + m_pPackageDescriptionEdit = new QLineEdit(this); + m_pPackageDescriptionEdit->setText(QString()); + pLabel->setBuddy(m_pPackageDescriptionEdit); + pLayout->addWidget(m_pPackageDescriptionEdit,3,1); + + pLabel = new QLabel(this); + pLabel->setText(__tr2qs_ctx("Minimum &KVIrc Version:","addon")); + pLayout->addWidget(pLabel,4,0); + + m_pPackageMinVersionEdit = new QLineEdit(this); + m_pPackageMinVersionEdit->setText(KVI_VERSION); + pLabel->setBuddy(m_pPackageMinVersionEdit); + pLayout->addWidget(m_pPackageMinVersionEdit,4,1); + + // Store data in the fields + registerField("packageAuthor*",m_pPackageAuthorEdit); + registerField("packageName*",m_pPackageNameEdit); + registerField("packageVersion*",m_pPackageVersionEdit); + registerField("packageDescription*",m_pPackageDescriptionEdit); + registerField("packageMinVersion",m_pPackageMinVersionEdit); +} + +PackAddonInfoPackageWidget::~PackAddonInfoPackageWidget() +{ +} + + +PackAddonFileSelectionWidget::PackAddonFileSelectionWidget(PackAddonDialog * pParent) +: QWizardPage(pParent) +{ + setObjectName("addon_package_file_page"); + setTitle(__tr2qs_ctx("Package Files","addon")); + setSubTitle(__tr2qs_ctx("Here you need to select the directory where the addon files are.","addon")); + + QVBoxLayout * pLayout = new QVBoxLayout(this); + + // Select source directory + m_pDirPathSelector = new KviDirectorySelector(this,__tr2qs_ctx("Select the source directory:","addon"),&m_szDirPath,true,KviFileSelector::VerticalLayout); + pLayout->addWidget(m_pDirPathSelector); + + // Select addon icon + m_pPackageIconEdit = new KviFileSelector(this,__tr2qs_ctx("Select the icon file:","addon"),&m_szPackageIcon,true,KviFileSelector::VerticalLayout,KVI_FILTER_IMAGE); + pLayout->addWidget(m_pPackageIconEdit); + + // Store data in the fields + registerField("packageDirPath*",m_pDirPathSelector); + registerField("packageIcon*",m_pPackageIconEdit); +} + +PackAddonFileSelectionWidget::~PackAddonFileSelectionWidget() +{ +} + + +PackAddonSaveSelectionWidget::PackAddonSaveSelectionWidget(PackAddonDialog * pParent) +: QWizardPage(pParent) +{ + setObjectName("addon_package_save_page"); + setTitle(__tr2qs_ctx("Save Package","addon")); + setSubTitle(__tr2qs_ctx("Here you need to provide the path where to save the addon package","addon")); + + QVBoxLayout * pLayout = new QVBoxLayout(this); + + // Select save path + m_pSavePathSelector = new KviFileSelector( + this, + __tr2qs_ctx("Select save path:","addon"), + &m_szFilePath, + true, + KviFileSelector::ChooseSaveFileName | KviFileSelector::VerticalLayout, + KVI_FILTER_ADDON + ); + pLayout->addWidget(m_pSavePathSelector); + + // Store data in the fields + registerField("packageSavePath*",m_pSavePathSelector); +} + +PackAddonSaveSelectionWidget::~PackAddonSaveSelectionWidget() +{ +} + +void PackAddonSaveSelectionWidget::initializePage() +{ + // Get data from registered fields + QString szName = field("packageName").toString(); + QString szVersion = field("packageVersion").toString(); + + // Create addon name + QString szSavePath = QDir::homePath(); + KviQString::ensureLastCharIs(szSavePath,QChar(KVI_PATH_SEPARATOR_CHAR)); + szSavePath += szName; + szSavePath += "-"; + szSavePath += szVersion; + szSavePath += KVI_FILEEXTENSION_ADDONPACKAGE; + m_pSavePathSelector->setTmpFile(szSavePath); +} + + +PackAddonSummaryInfoWidget::PackAddonSummaryInfoWidget(PackAddonDialog * pParent) +: QWizardPage(pParent) +{ + setObjectName("addon_package_summary_info_page"); + setTitle(__tr2qs_ctx("Final Information","addon")); + setSubTitle(__tr2qs_ctx("Here there are the information you provided. If these information are correct, hit the \"Finish\" button to complete the packaging operations.","addon")); + + QVBoxLayout * pLayout = new QVBoxLayout(this); + m_pLabelInfo = new QLabel(this); + pLayout->addWidget(m_pLabelInfo); +} + +PackAddonSummaryInfoWidget::~PackAddonSummaryInfoWidget() +{ +} + +void PackAddonSummaryInfoWidget::initializePage() +{ + // Get data from registered fields + QString szAuthor = field("packageAuthor").toString(); + QString szName = field("packageName").toString(); + QString szVersion = field("packageVersion").toString(); + QString szDescription = field("packageDescription").toString(); + QString szMinVersion = field("packageMinVersion").toString(); + QString szIcon = field("packageIcon").toString(); + QString szDirPath = field("packageDirPath").toString(); + QString szSavePath = field("packageSavePath").toString(); + + QString szText = __tr2qs_ctx("This is what I will check for:","addon"); + szText += "

"; + szText += __tr2qs_ctx("Package Author","addon"); + szText += ": "; + szText += szAuthor; + szText += "
"; + szText += __tr2qs_ctx("Package Name","addon"); + szText += ": "; + szText += szName; + szText += "
"; + szText += __tr2qs_ctx("Package Version","addon"); + szText += ": "; + szText += szVersion; + szText += "
"; + szText += __tr2qs_ctx("Package Description","addon"); + szText += ": "; + szText += szDescription; + szText += "
"; + szText += __tr2qs_ctx("Minimum KVIrc Version","addon"); + szText += ": "; + szText += szMinVersion; + szText += "
"; + szText += __tr2qs_ctx("Icon File","addon"); + szText += ": "; + szText += szIcon; + szText += "
"; + szText += __tr2qs_ctx("Source Directory","addon"); + szText += ": "; + szText += szDirPath; + szText += "
"; + szText += __tr2qs_ctx("Save Path","addon"); + szText += ": "; + szText += szSavePath; + + m_pLabelInfo->setText(szText); +} + + +PackAddonSummaryFilesWidget::PackAddonSummaryFilesWidget(PackAddonDialog * pParent) +: QDialog(pParent) +{ + setObjectName("addon_package_summary_file_dialog"); + setWindowTitle(__tr2qs_ctx("File Summary","addon")); + setWindowModality(Qt::WindowModal); + setModal(true); + + QVBoxLayout * pLayout = new QVBoxLayout(this); + + QLabel * pLabel = new QLabel(this); + pLabel->setText(__tr2qs_ctx("Here there are the files I found in the directories you provided.\nIf these and the information showed in the previous page are correct, hit the \"Finish\" button to complete\nthe packaging operations.","addon")); + pLayout->addWidget(pLabel); + + m_pFiles = new QTextEdit(this); + m_pFiles->setReadOnly(true); + pLayout->addWidget(m_pFiles); + + KviTalHBox * pBox = new KviTalHBox(this); + QPushButton * pCancel = new QPushButton(pBox); + pCancel->setText(__tr2qs_ctx("Cancel","addon")); + connect(pCancel,SIGNAL(clicked()),this,SLOT(reject())); + + QPushButton * pAccept = new QPushButton(pBox); + pAccept->setText(__tr2qs_ctx("Finish","addon")); + connect(pAccept,SIGNAL(clicked()),this,SLOT(accept())); + pLayout->addWidget(pBox); +} + +PackAddonSummaryFilesWidget::~PackAddonSummaryFilesWidget() +{ +} + +void PackAddonSummaryFilesWidget::accept() +{ + QDialog::accept(); +} + +void PackAddonSummaryFilesWidget::reject() +{ + QDialog::reject(); +} + +void PackAddonSummaryFilesWidget::showEvent(QShowEvent *) +{ + QStringList list; + + QDirIterator it(m_szPath,QDir::AllEntries | QDir::NoDotAndDotDot,QDirIterator::Subdirectories); + + // Iterate through the addon dir and its subdirs + while(it.hasNext()) + { + QString szStr = it.next(); + if(!szStr.contains("/.")) + list.append(szStr); + } + + // QDirIterator does not support sorting, so do it manually + list.sort(); + + m_pFiles->setPlainText(list.join("\n")); +} diff --git a/src/modules/addon/PackAddonDialog.h b/src/modules/addon/PackAddonDialog.h new file mode 100644 index 000000000..5819a8186 --- /dev/null +++ b/src/modules/addon/PackAddonDialog.h @@ -0,0 +1,252 @@ +#ifndef _PACKADDONDIALOG_H_ +#define _PACKADDONDIALOG_H_ +//============================================================================= +// +// File : PackAddonDialog.h +// Creation date : Sat 03 May 2008 01:40:44 by Elvio Basello +// +// This file is part of the KVIrc IRC Client distribution +// Copyright (C) 2008-2009 Elvio Basello +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +/** +* \file PackAddonDialog.h +* \author Elvio Basello +* \brief Addon package creator +* +* This set of classes allow users to create addon for KVIrc in a standard +* distributable *.kva packages. +*/ + +#include "kvi_settings.h" +#include "KviPointerList.h" +#include "KviSelectors.h" + +#include +#include + +class QTextEdit; +class QLineEdit; +class QLabel; + +class KviPackageWriter; + +class PackAddonInfoPackageWidget; +class PackAddonFileSelectionWidget; +class PackAddonSaveSelectionWidget; +class PackAddonSummaryInfoWidget; +class PackAddonSummaryFilesWidget; + +/** +* \class PackAddonDialog +* \brief Wizard for addon creation +*/ +class PackAddonDialog : public QWizard +{ + Q_OBJECT +public: + /** + * \brief Creates the wizard object + * \param pParent The parent widget + * \return PackAddonDialog + */ + PackAddonDialog(QWidget * pParent); + + /** + * \brief Destroys the wizard object + */ + ~PackAddonDialog(); +protected: + PackAddonInfoPackageWidget * m_pPackAddonInfoPackageWidget; + PackAddonFileSelectionWidget * m_pPackAddonFileSelectionWidget; + PackAddonSaveSelectionWidget * m_pPackAddonSaveSelectionWidget; + PackAddonSummaryInfoWidget * m_pPackAddonSummaryInfoWidget; + PackAddonSummaryFilesWidget * m_pPackAddonSummaryFilesWidget; + QString m_szAuthor; + QString m_szName; + QString m_szVersion; + QString m_szDescription; + QString m_szMinVersion; + QString m_szIcon; + QString m_szDirPath; + QString m_szSavePath; +protected: + /** + * \brief Runs the packAddon() function and closes the wizard + * \return void + */ + virtual void accept(); + + /** + * \brief Creates the addon package + * \return bool + */ + bool packAddon(); + + /** + * \brief Ensures the sources directory is complete + * \param pszError The buffer containing errors + * \param pszWarning The buffer containing warnings + * \return bool + */ + bool checkDirTree(QString * pszError, QString * pszWarning); + + /** + * \brief Creates the installer file + * \param pszError The buffer containing errors + * \return bool + */ + bool createInstaller(QString * pszError); +}; + +/** +* \class PackAddonInfoPackageWidget +* \brief Wizard page for addon information +*/ +class PackAddonInfoPackageWidget : public QWizardPage +{ + Q_OBJECT +public: + /** + * \brief Create the wizard package info page object + * \param pParent The parent widget + * \return PackAddonInfoPackageWidget + */ + PackAddonInfoPackageWidget(PackAddonDialog * pParent); + + /** + * \brief Destroys the wizard package info page object + */ + ~PackAddonInfoPackageWidget(); +protected: + QLineEdit * m_pPackageAuthorEdit; + QLineEdit * m_pPackageNameEdit; + QLineEdit * m_pPackageVersionEdit; + QLineEdit * m_pPackageDescriptionEdit; + QLineEdit * m_pPackageMinVersionEdit; +}; + +/** +* \class PackAddonFileSelectionWidget +* \brief Wizard page for directory source selection +*/ +class PackAddonFileSelectionWidget : public QWizardPage +{ + Q_OBJECT +public: + /** + * \brief Create the wizard package source dir object + * \param pParent The parent widget + * \return PackAddonFileSelectionWidget + */ + PackAddonFileSelectionWidget(PackAddonDialog * pParent); + + /** + * \brief Destroys the wizard package source dir object + */ + ~PackAddonFileSelectionWidget(); +protected: + KviDirectorySelector * m_pDirPathSelector; + KviFileSelector * m_pPackageIconEdit; + QString m_szDirPath; + QString m_szPackageIcon; +}; + +/** +* \class PackAddonSaveSelectionWidget +* \brief Wizard page for saving package +*/ +class PackAddonSaveSelectionWidget : public QWizardPage +{ + Q_OBJECT +public: + /** + * \brief Create the wizard save page object + * \param pParent The parent widget + * \return PackAddonSaveSelectionWidget + */ + PackAddonSaveSelectionWidget(PackAddonDialog * pParent); + + /** + * \brief Destroys the wizard save page object + */ + ~PackAddonSaveSelectionWidget(); +protected: + KviFileSelector * m_pSavePathSelector; + QString m_szFilePath; +protected: + /** + * \brief Perform initial tasks before showing the widget + * \return void + */ + virtual void initializePage(); +}; + +/** +* \class PackAddonSummaryInfoWidget +* \brief Wizard page for showing information inserted +*/ +class PackAddonSummaryInfoWidget : public QWizardPage +{ + Q_OBJECT +public: + /** + * \brief Create the wizard summary info page object + * \param pParent The parent widget + * \return PackAddonSummaryInfoWidget + */ + PackAddonSummaryInfoWidget(PackAddonDialog * pParent); + + /** + * \brief Destroys the wizard summary info page object + */ + ~PackAddonSummaryInfoWidget(); +protected: + QLabel * m_pLabelInfo; + QLabel * m_pLabelAuthor; + QLabel * m_pPackageName; + QLabel * m_pPackageVersion; + QLabel * m_pPackageDescription; +protected: + /** + * \brief Perform initial tasks before showing the widget + * \return void + */ + virtual void initializePage(); +}; + + +class PackAddonSummaryFilesWidget : public QDialog +{ + Q_OBJECT +public: + PackAddonSummaryFilesWidget(PackAddonDialog * pParent); + ~PackAddonSummaryFilesWidget(); +protected: + QTextEdit * m_pFiles; + QString m_szPath; +public: + void setPath(QString & szPath){ m_szPath = szPath; }; +protected: + virtual void showEvent(QShowEvent *); +protected slots: + virtual void accept(); + virtual void reject(); +}; + +#endif //!_PACKADDONDIALOG_H_ diff --git a/src/modules/addon/addonfunctions.cpp b/src/modules/addon/addonfunctions.cpp deleted file mode 100644 index 590935319..000000000 --- a/src/modules/addon/addonfunctions.cpp +++ /dev/null @@ -1,272 +0,0 @@ -//============================================================================= -// -// File : addonfunctions.cpp -// Creation date : Fri 02 May 2008 17:36:07 by Elvio Basello -// -// This file is part of the KVIrc IRC Client distribution -// Copyright (C) 2008 Elvio Basello -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "addonfunctions.h" - -#include "KviPackageReader.h" -#include "KviLocale.h" -#include "KviMessageBox.h" -#include "KviApplication.h" -#include "KviHtmlDialog.h" -#include "KviIconManager.h" -#include "KviFileUtils.h" -#include "KviMiscUtils.h" -#include "kvi_sourcesdate.h" -#include "KviMainWindow.h" -#include "KviKvsScript.h" - -#include - -#include - -namespace KviAddonFunctions -{ - bool notAValidAddonPackage(QString &szError) - { - szError = __tr2qs_ctx("The selected file does not seem to be a valid KVIrc addon package","addon"); - return false; - } - - bool installAddonPackage(const QString &szAddonPackageFileName,QString &szError,QWidget * pDialogParent) - { - KviPointerHashTable * pInfoFields; - QString * pValue; - QString szErr; - QPixmap pix; - QByteArray * pByteArray; - bool bInstall; - KviHtmlDialogData hd; - - const char * check_fields[] = { "Name", "Version", "Author", "Description", "Date", "Application" }; - - // check if it is a valid addon file - KviPackageReader r; - if(!r.readHeader(szAddonPackageFileName)) - { - szErr = r.lastError(); - KviQString::sprintf(szError,__tr2qs_ctx("The selected file does not seem to be a valid KVIrc package: %Q","addon"),&szErr); - return false; - } - - pInfoFields = r.stringInfoFields(); - - pValue = pInfoFields->find("PackageType"); - - if(!pValue) - return notAValidAddonPackage(szError); - - if(!KviQString::equalCI(*pValue,"AddonPack")) - return notAValidAddonPackage(szError); - - pValue = pInfoFields->find("AddonPackVersion"); - - if(!pValue) - return notAValidAddonPackage(szError); - - // make sure the default fields exist - for(int i=0;i<6;i++) - { - pValue = pInfoFields->find(check_fields[i]); - if(!pValue) - return notAValidAddonPackage(szError); - } - - // ok.. it should be really valid at this point - // load its picture - pByteArray = r.binaryInfoFields()->find("Image"); - if(pByteArray) - pix.loadFromData(*pByteArray,0,0); - - if(pix.isNull()) - { - // load the default icon - pix = *(g_pIconManager->getBigIcon(KVI_BIGICON_ADDONS)); - } - - QString szPackageName; - QString szPackageVersion; - QString szPackageAuthor; - QString szPackageDescription; - QString szPackageDate; - QString szAddonPackVersion; - QString szPackageApplication; - - QString szAuthor = __tr2qs_ctx("Author","addon"); - QString szCreatedAt = __tr2qs_ctx("Created at","addon"); - QString szCreatedWith = __tr2qs_ctx("Created with","addon"); - - r.getStringInfoField("Name",szPackageName); - r.getStringInfoField("Version",szPackageVersion); - r.getStringInfoField("Author",szPackageAuthor); - r.getStringInfoField("Description",szPackageDescription); - r.getStringInfoField("Application",szPackageApplication); - r.getStringInfoField("Date",szPackageDate); - r.getStringInfoField("AddonPackVersion",szAddonPackVersion); - - QString szWarnings; - QString szTmp; - - bool bValid = true; - - if(szPackageName.isEmpty() || szPackageVersion.isEmpty() || szAddonPackVersion.isEmpty()) - bValid = false; - - if(KviMiscUtils::compareVersions(szAddonPackVersion,KVI_CURRENT_ADDONS_ENGINE_VERSION) < 0) - bValid = false; - - - if(!bValid) - { - szWarnings += "

"; - szWarnings += __tr2qs_ctx("Warning: The addon might be incompatible with this version of KVIrc","addon"); - szWarnings += "

"; - } - - KviQString::sprintf(hd.szHtmlText, - "" \ - "" \ - "

" \ - "

%Q %Q

" \ - "

" \ - "

" \ - "" \ - "

" \ - "

" \ - "%Q" \ - "

" \ - "

" \ - "%Q: %Q
" \ - "%Q: %Q
" \ - "

" \ - "

" \ - "" \ - "%Q: %Q
" \ - "
" \ - "

" \ - "%Q" \ - "
" \ - "" \ - "", - &szPackageName, - &szPackageVersion, - &szPackageDescription, - &szAuthor, - &szPackageAuthor, - &szCreatedAt, - &szPackageDate, - &szCreatedWith, - &szPackageApplication, - &szWarnings - ); - - hd.addImageResource("addon_dialog_pack_image",pix); - hd.addHtmlResource("addon_dialog_main",hd.szHtmlText); - - QString beginCenter = "
"; - QString endCenter = "
"; - - hd.szCaption = __tr2qs_ctx("Install Addon Pack - KVIrc","addon"); - hd.szUpperLabelText = beginCenter + __tr2qs_ctx("You're about to install the following addon package","addon") + endCenter; - hd.szLowerLabelText = beginCenter + __tr2qs_ctx("Do you want to proceed with the installation ?","addon") + endCenter; - hd.szButton1Text = __tr2qs_ctx("Do Not Install","addon"); - hd.szButton2Text = __tr2qs_ctx("Yes, Proceed","addon"); - hd.iDefaultButton = 2; - hd.iCancelButton = 1; - hd.pixIcon = *(g_pIconManager->getSmallIcon(KVI_SMALLICON_ADDONS)); - hd.iMinimumWidth = 350; - hd.iMinimumHeight = 420; - hd.iFlags = KviHtmlDialogData::ForceMinimumSize; - - bInstall = KviHtmlDialog::display(pDialogParent,&hd) == 2; - - if(!bInstall) - return true; - - // Create a random extraction dir - QString szTmpPath, szUnpackPath; - QString szRandomDir = createRandomDir(); - - g_pApp->getLocalKvircDirectory(szTmpPath,KviApplication::Tmp); - KviQString::ensureLastCharIs(szTmpPath,QChar(KVI_PATH_SEPARATOR_CHAR)); - szUnpackPath = szTmpPath + szRandomDir; - QDir szTmpDir(szUnpackPath); - - // Check for dir existence - while(szTmpDir.exists()) - { - szRandomDir = createRandomDir(); - szUnpackPath = szTmpPath + szRandomDir; - szTmpDir = QDir(szUnpackPath); - } - - // Unpack addon package into the random tmp dir - if(!r.unpack(szAddonPackageFileName,szUnpackPath)) - { - szErr = r.lastError(); - KviQString::sprintf(szError,__tr2qs_ctx("Failed to unpack the selected file: %Q","addon"),&szErr); - return false; - } - - // Now we have all stuff in ~/.config/KVIrc/tmp/$rand - KviQString::escapeKvs(&szUnpackPath, KviQString::EscapeSpace); - if(!KviKvsScript::run(QString::fromAscii("parse %1/install.kvs").arg(szUnpackPath), g_pActiveWindow)) - { - // Parsing the script failed - // However, the user should already be notified via normal script output. - } - - if(!KviFileUtils::deleteDir(szUnpackPath)) - { - // FIXME: Just warn the user and assume success? - szErr = __tr2qs_ctx("One or more files can't be deleted","addon"); - KviQString::sprintf(szError,__tr2qs_ctx("Failed to unpack the selected file: %Q","addon"),&szErr); - return false; - } - - return true; - } - - QString createRandomDir() - { - QString szDirName; - char chars[] = { - 'A','B','C','D','E','F','G','H', - 'I','J','K','L','M','N','O','P', - 'Q','R','S','T','U','V','W','X', - 'Y','Z','a','b','c','d','e','f', - 'g','h','i','j','k','l','m','n', - 'o','p','q','r','s','t','u','v', - 'w','x','y','z','-','_','.' - }; - - // Generate dir name - for(int i=0;i<10;i++) - { - int n = rand() % sizeof(chars); - szDirName.append(chars[n]); - } - - return szDirName; - } -} diff --git a/src/modules/addon/addonfunctions.h b/src/modules/addon/addonfunctions.h deleted file mode 100644 index c8b39e9b0..000000000 --- a/src/modules/addon/addonfunctions.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _ADDONFUNCTIONS_H_ -#define _ADDONFUNCTIONS_H_ -//============================================================================= -// -// File : addonfunctions.h -// Creation date : Fri 02 May 2008 17:36:07 by Elvio Basello -// -// This file is part of the KVIrc IRC Client distribution -// Copyright (C) 2008 Elvio Basello -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "kvi_settings.h" -#include "KviQString.h" - -#include -#include - -#define KVI_CURRENT_ADDONS_ENGINE_VERSION "2.0.0" - -namespace KviAddonFunctions -{ - bool notAValidAddonPackage(QString & szError); - bool installAddonPackage(const QString & szAddonPackageFileName, QString & szError, QWidget * pDialogParent = 0); - QString createRandomDir(); -} - -#endif //!_ADDONFUNCTIONS_H_ diff --git a/src/modules/addon/libkviaddon.cpp b/src/modules/addon/libkviaddon.cpp index 79f39a851..c852c5b13 100644 --- a/src/modules/addon/libkviaddon.cpp +++ b/src/modules/addon/libkviaddon.cpp @@ -23,7 +23,7 @@ //============================================================================= #include "managementdialog.h" -#include "addonfunctions.h" +#include "AddonFunctions.h" #include "KviModule.h" #include "KviKvsScriptAddonManager.h" @@ -776,7 +776,7 @@ static bool addon_kvs_cmd_installfiles(KviKvsModuleCommandCall * c) static bool addon_kvs_cmd_dialog(KviKvsModuleCommandCall *c) { - KviScriptManagementDialog::display(c->hasSwitch('t',"toplevel")); + AddonManagementDialog::display(c->hasSwitch('t',"toplevel")); return true; } @@ -803,7 +803,7 @@ static bool addon_kvs_cmd_install(KviKvsModuleCommandCall * c) KVSM_PARAMETERS_END(c) QString szError; - if(!KviAddonFunctions::installAddonPackage(szAddonPackFile,szError)) + if(!AddonFunctions::installAddonPackage(szAddonPackFile,szError)) { c->error(__tr2qs_ctx("Error installing addon package: %Q","addon"),&szError); return false; @@ -839,7 +839,7 @@ static bool addon_module_init(KviModule *m) static bool addon_module_cleanup(KviModule *m) { - KviScriptManagementDialog::cleanup(); + AddonManagementDialog::cleanup(); QString szBuf; m->getDefaultConfigFileName(szBuf); @@ -851,7 +851,7 @@ static bool addon_module_cleanup(KviModule *m) static bool addon_module_can_unload(KviModule *) { - return (!KviScriptManagementDialog::instance()); + return (!AddonManagementDialog::instance()); } diff --git a/src/modules/addon/managementdialog.cpp b/src/modules/addon/managementdialog.cpp index 846c5e112..d2f4d2ef9 100644 --- a/src/modules/addon/managementdialog.cpp +++ b/src/modules/addon/managementdialog.cpp @@ -23,8 +23,8 @@ //============================================================================= #include "managementdialog.h" -#include "packaddondialog.h" -#include "addonfunctions.h" +#include "PackAddonDialog.h" +#include "AddonFunctions.h" #include "KviApplication.h" #include "KviLocale.h" @@ -56,10 +56,10 @@ #include -KviScriptManagementDialog * KviScriptManagementDialog::m_pInstance = 0; +AddonManagementDialog * AddonManagementDialog::m_pInstance = 0; extern QRect g_rectManagementDialogGeometry; -KviScriptAddonListViewItem::KviScriptAddonListViewItem(KviTalListWidget *v,KviKvsScriptAddon * a) +AddonListViewItem::AddonListViewItem(KviTalListWidget *v,KviKvsScriptAddon * a) : KviTalListWidgetItem(v) { m_pAddon = new KviKvsScriptAddon(*a); @@ -81,12 +81,12 @@ KviScriptAddonListViewItem::KviScriptAddonListViewItem(KviTalListWidget *v,KviKv if (p) setIcon(*p); } -KviScriptAddonListViewItem::~KviScriptAddonListViewItem() +AddonListViewItem::~AddonListViewItem() { delete m_pAddon; } -KviScriptManagementDialog::KviScriptManagementDialog(QWidget * p) +AddonManagementDialog::AddonManagementDialog(QWidget * p) : QWidget(p) { setWindowTitle(__tr2qs_ctx("Manage Script-Based Addons","addon")); @@ -186,13 +186,13 @@ KviScriptManagementDialog::KviScriptManagementDialog(QWidget * p) g_rectManagementDialogGeometry.y()); } -KviScriptManagementDialog::~KviScriptManagementDialog() +AddonManagementDialog::~AddonManagementDialog() { g_rectManagementDialogGeometry = QRect(pos().x(),pos().y(),size().width(),size().height()); m_pInstance = 0; } -void KviScriptManagementDialog::fillListView() +void AddonManagementDialog::fillListView() { m_pListWidget->clear(); KviPointerHashTable * d = KviKvsScriptAddonManager::instance()->addonDict(); @@ -201,14 +201,14 @@ void KviScriptManagementDialog::fillListView() while(KviKvsScriptAddon * a = it.current()) { - new KviScriptAddonListViewItem(m_pListWidget,a); + new AddonListViewItem(m_pListWidget,a); ++it; } } -void KviScriptManagementDialog::currentChanged(QListWidgetItem *item,QListWidgetItem *) +void AddonManagementDialog::currentChanged(QListWidgetItem *item,QListWidgetItem *) { - KviScriptAddonListViewItem * it = (KviScriptAddonListViewItem *)item; + AddonListViewItem * it = (AddonListViewItem *)item; if(!it) { m_pConfigureButton->setEnabled(false); @@ -221,32 +221,32 @@ void KviScriptManagementDialog::currentChanged(QListWidgetItem *item,QListWidget } } -void KviScriptManagementDialog::showScriptHelp() +void AddonManagementDialog::showScriptHelp() { - KviScriptAddonListViewItem * it = (KviScriptAddonListViewItem *)m_pListWidget->currentItem(); + AddonListViewItem * it = (AddonListViewItem *)m_pListWidget->currentItem(); if(!it)return; if(it->addon()->helpCallbackCode().isEmpty())return; it->addon()->executeHelpCallback(g_pActiveWindow); } -void KviScriptManagementDialog::configureScript() +void AddonManagementDialog::configureScript() { - KviScriptAddonListViewItem * it = (KviScriptAddonListViewItem *)m_pListWidget->currentItem(); + AddonListViewItem * it = (AddonListViewItem *)m_pListWidget->currentItem(); if(!it)return; if(it->addon()->configureCallbackCode().isEmpty())return; it->addon()->executeConfigureCallback(g_pActiveWindow); } -void KviScriptManagementDialog::packScript() +void AddonManagementDialog::packScript() { - KviPackAddonDialog * pDialog = new KviPackAddonDialog(this); + PackAddonDialog * pDialog = new PackAddonDialog(this); pDialog->exec(); delete pDialog; } -void KviScriptManagementDialog::uninstallScript() +void AddonManagementDialog::uninstallScript() { - KviScriptAddonListViewItem * it = (KviScriptAddonListViewItem *)m_pListWidget->currentItem(); + AddonListViewItem * it = (AddonListViewItem *)m_pListWidget->currentItem(); if(!it)return; QString txt = "

"; @@ -265,13 +265,13 @@ void KviScriptManagementDialog::uninstallScript() currentChanged(0,0); } -void KviScriptManagementDialog::getMoreScripts() +void AddonManagementDialog::getMoreScripts() { // If change this introducing not-fixed text, remember to escape this using KviQString::escapeKvs()! KviKvsScript::run("openurl http://www.kvirc.net/?id=addons&version=" KVI_VERSION "." KVI_SOURCES_DATE,g_pActiveWindow); } -void KviScriptManagementDialog::installScript() +void AddonManagementDialog::installScript() { QString szFileName, szError; @@ -286,7 +286,7 @@ void KviScriptManagementDialog::installScript() // Sanity check if(szFileName.endsWith(".kva")) { - if(!KviAddonFunctions::installAddonPackage(szFileName,szError,this)) + if(!AddonFunctions::installAddonPackage(szFileName,szError,this)) { QMessageBox::critical( this, @@ -301,7 +301,7 @@ void KviScriptManagementDialog::installScript() } else { // Just for sanity check. We should NEVER enter here qDebug("Entered sanity check"); - KviAddonFunctions::notAValidAddonPackage(szError); + AddonFunctions::notAValidAddonPackage(szError); QMessageBox::critical( this, __tr2qs_ctx("Install Addon - KVIrc","addon"), @@ -319,7 +319,7 @@ void KviScriptManagementDialog::installScript() //m_pListWidget->triggerUpdate(); } -void KviScriptManagementDialog::showEvent(QShowEvent * e) +void AddonManagementDialog::showEvent(QShowEvent * e) { QRect rect = g_pApp->desktop()->screenGeometry(g_pApp->desktop()->primaryScreen()); move((rect.width() - width())/2,(rect.height() - height())/2); @@ -327,19 +327,19 @@ void KviScriptManagementDialog::showEvent(QShowEvent * e) QWidget::showEvent(e); } -void KviScriptManagementDialog::closeClicked() +void AddonManagementDialog::closeClicked() { delete this; } -void KviScriptManagementDialog::cleanup() +void AddonManagementDialog::cleanup() { if(!m_pInstance)return; delete m_pInstance; m_pInstance = 0; } -void KviScriptManagementDialog::display(bool bTopLevel) +void AddonManagementDialog::display(bool bTopLevel) { if(m_pInstance) { @@ -358,9 +358,9 @@ void KviScriptManagementDialog::display(bool bTopLevel) } else { if(bTopLevel) { - m_pInstance = new KviScriptManagementDialog(0); + m_pInstance = new AddonManagementDialog(0); } else { - m_pInstance = new KviScriptManagementDialog(g_pFrame->splitter()); + m_pInstance = new AddonManagementDialog(g_pFrame->splitter()); } } m_pInstance->show(); @@ -368,13 +368,13 @@ void KviScriptManagementDialog::display(bool bTopLevel) m_pInstance->setFocus(); } -void KviScriptManagementDialog::closeEvent(QCloseEvent * e) +void AddonManagementDialog::closeEvent(QCloseEvent * e) { e->ignore(); delete this; } -void KviScriptManagementDialog::reject() +void AddonManagementDialog::reject() { cleanup(); } diff --git a/src/modules/addon/managementdialog.h b/src/modules/addon/managementdialog.h index 45a6b8656..dd9fe1780 100644 --- a/src/modules/addon/managementdialog.h +++ b/src/modules/addon/managementdialog.h @@ -38,11 +38,11 @@ class QPixmap; class KviKvsScriptAddon; -class KviScriptAddonListViewItem : public KviTalListWidgetItem +class AddonListViewItem : public KviTalListWidgetItem { public: - KviScriptAddonListViewItem(KviTalListWidget * v,KviKvsScriptAddon * a); - ~KviScriptAddonListViewItem(); + AddonListViewItem(KviTalListWidget * v,KviKvsScriptAddon * a); + ~AddonListViewItem(); protected: KviKvsScriptAddon * m_pAddon; QTextDocument * m_pText; @@ -54,22 +54,22 @@ public: }; -class KviScriptManagementDialog : public QWidget +class AddonManagementDialog : public QWidget { Q_OBJECT protected: - KviScriptManagementDialog(QWidget * p); + AddonManagementDialog(QWidget * p); public: - ~KviScriptManagementDialog(); + ~AddonManagementDialog(); protected: KviTalListWidget * m_pListWidget; - static KviScriptManagementDialog * m_pInstance; + static AddonManagementDialog * m_pInstance; QToolButton * m_pConfigureButton; QToolButton * m_pHelpButton; QToolButton * m_pPackButton; QToolButton * m_pUninstallButton; public: - static KviScriptManagementDialog * instance(){ return m_pInstance; }; + static AddonManagementDialog * instance(){ return m_pInstance; }; static void display(bool bTopLevel); static void cleanup(); protected: diff --git a/src/modules/addon/packaddondialog.cpp b/src/modules/addon/packaddondialog.cpp deleted file mode 100644 index ce2c52890..000000000 --- a/src/modules/addon/packaddondialog.cpp +++ /dev/null @@ -1,664 +0,0 @@ -//============================================================================ -// -// File : packaddondialog.cpp -// Creation date : Sat 03 May 2008 01:40:44 by Elvio Basello -// -// This file is part of the KVIrc IRC Client distribution -// Copyright (C) 2008-2009 Elvio Basello -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================ - -#include "packaddondialog.h" -#include "addonfunctions.h" - -#include "KviLocale.h" -#include "KviFileUtils.h" -#include "KviApplication.h" -#include "KviIconManager.h" -#include "KviPackageWriter.h" -#include "kvi_fileextensions.h" -#include "kvi_sourcesdate.h" -#include "KviOptions.h" - -#include -#include -#include -#include -#include -#include -#include -#include - - -KviPackAddonDialog::KviPackAddonDialog(QWidget * pParent) -: QWizard(pParent) -{ - setMinimumSize(400,350); - setObjectName("addon_package_wizard"); - setOption(QWizard::IndependentPages,true); - setWindowTitle(__tr2qs_ctx("Create Addon Package - KVIrc","addon")); - - QPixmap * pSide = g_pIconManager->getBigIcon("kvi_setup_label.png"); - QPixmap * pLogo = g_pIconManager->getBigIcon("kvi_bigicon_addons.png"); - -#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - #if (_WIN32_WINNT >= 0x0600) - // We are on a Windows Vista / Seven - // It will fallback to XP if alpha compositing is disabled - setWizardStyle(QWizard::AeroStyle); - #else - // Windows XP - setWizardStyle(QWizard::ModernStyle); - setPixmap(QWizard::WatermarkPixmap,*pSide); - setPixmap(QWizard::LogoPixmap,*pLogo); - #endif -#elif defined(COMPILE_ON_MAC) - setWizardStyle(QWizard::MacStyle); - setPixmap(QWizard::BackgroundPixmap,*pSide); -#else - // All other systems - setWizardStyle(QWizard::ClassicStyle); - setPixmap(QWizard::WatermarkPixmap,*pSide); - setPixmap(QWizard::LogoPixmap,*pLogo); -#endif - - // Add a default property for file selectors - setDefaultProperty("KviFileSelector","tmpFile",SIGNAL(selectionChanged(const QString &))); - - // Welcome page - QWizardPage * pPage = new QWizardPage(this); - QVBoxLayout * pLayout = new QVBoxLayout(pPage); - - pPage->setLayout(pLayout); - pPage->setTitle(__tr2qs_ctx("Welcome","addon")); - - QLabel * pLabel = new QLabel(pPage); - pLabel->setWordWrap(true); - pLabel->setText(__tr2qs_ctx("This procedure allows you to export the selected addon to a single package. It is useful when you want to distribute your addon to the public.","addon")); - pLayout->addWidget(pLabel); - - pLabel = new QLabel(pPage); - pLabel->setWordWrap(true); - QString szText; - szText += __tr2qs_ctx("You will be asked to provide some information like the package name, the version, a description and so on.","addon"); - szText += "

"; - szText += __tr2qs_ctx("Hit the \"Next\" button to begin.","addon"); - pLabel->setText(szText); - pLayout->addWidget(pLabel); - - pPage->setMinimumWidth(350); - - addPage(pPage); - - // Packager information - m_pPackAddonInfoPackageWidget = new KviPackAddonInfoPackageWidget(this); - addPage(m_pPackAddonInfoPackageWidget); - - // File selection - m_pPackAddonFileSelectionWidget = new KviPackAddonFileSelectionWidget(this); - addPage(m_pPackAddonFileSelectionWidget); - - // Save selection - m_pPackAddonSaveSelectionWidget = new KviPackAddonSaveSelectionWidget(this); - addPage(m_pPackAddonSaveSelectionWidget); - - // Summary info - m_pPackAddonSummaryInfoWidget = new KviPackAddonSummaryInfoWidget(this); - addPage(m_pPackAddonSummaryInfoWidget); - -} - -KviPackAddonDialog::~KviPackAddonDialog() -{ -} - -void KviPackAddonDialog::accept() -{ - if(!packAddon()) - return; - QWizard::accept(); -} - -bool KviPackAddonDialog::checkDirTree(QString * pszError, QString * pszWarning) -{ - if(pszError) *pszError = ""; - if(pszWarning) *pszWarning = ""; - - QDir addon(m_szDirPath); - if(!addon.exists()) - { - *pszError = __tr2qs_ctx("The selected directory does not exist.","addon"); - return false; - } - - QFileInfo init(m_szDirPath + "/install.kvs"); - if(!init.exists()) - { - *pszError = __tr2qs_ctx("The initialization script (install.kvs) does not exist.","addon"); - return false; - } - - return true; -} - -#if 0 -bool KviPackAddonDialog::createInstaller(QString * pszError) -{ - if(pszError) - *pszError = ""; - - // Start creating install.kvs: header - QString szTmp; - szTmp += QString("# This file is generated automatically. Do NOT touch unless you know what are you doing\n#\n"); - szTmp += QString("# %1 %2\n# Written by %3\n# %4\n\n").arg(m_szName, m_szVersion, m_szAuthor, m_szDescription); - szTmp += "# Register the script: this must be the first instruction executed\n# since it will abort with an error when a greater version is already installed\n"; - - // install.kvs: addon registration - /* FIXME: re-add in KVIrc 4.1! - * implement a backend with full automatic cleaning for aliases, classes, popups, - * actions, ... via snapshot/diff of kvirc state before/after installing a package - - szTmp += QString("addon.register(\"%1\",\"%2\",\"%1\",\"%3\",\"%4\",\"%5\")\n").arg(m_szName, m_szVersion, m_szDescription, m_szMinVersion, m_szIcon); - szTmp += "{\n"; - szTmp += "\t# This is our uninstall callback: it will be called by KVIrc when addon.uninstall is invoked\n"; - szTmp += QString("\t%1::uninstall::uninstall\n").arg(m_szName); - szTmp += QString("\t%1::uninstall::uninstallfiles\n").arg(m_szName); - szTmp += QString("\t%1::uninstall::uninstallaliases\n").arg(m_szName); - szTmp += "}\n\n"; - szTmp += "# Ok, addon.register succeeded. We can go on with the installation.\n\n"; - */ - - // install.kvs: run path - szTmp += "# Get the path that this script was launched from\n"; - szTmp += "%mypath = $file.extractPath($0)\n\n"; - - // install.kvs: create an instance of the installer class - szTmp += "# The installer will copy our files and generate automatically an uninstallation\n# alias for them\n"; - szTmp += "%installer = $new(installer,0,myaddon)\n\n"; - - // install.kvs: copy files - szTmp += "# Copy files in each subdirectory\n# the pics\n"; - - szTmp += QString("%installer->$copyFiles(\"%mypath/pics\",\"*.png\",$file.localdir(\"pics\"))\n\n"); - szTmp += "# the translations\n"; - szTmp += "%installer->$copyFiles(\"%mypath/locale\",\"*.mo\",$file.localdir(\"locale\"))\n\n"; - - szTmp += "# the documentation\n"; - szTmp += QString("%installer->$copyFiles(\"%mypath/help/\",\"*.html\",$file.localdir(\"help/\"))\n\n"); - - // install.kvs: generate uninstall alias - szTmp += "# Generate the uninstall alias\n"; - szTmp += QString("%installer->$generateUninstallAlias(\"%1::uninstallfiles\")\n\n") \ - .arg(m_szName); - - // kviinstall.kvs: kill the installer class - szTmp += "# Kill the installer helper\n"; - szTmp += "delete %installer\n\n"; - -#if 0 - // install.kvs: fetch the complete script - szTmp += "# Fetch the complete script\n"; - szTmp += "%files[] = $file.ls($file.extractpath($0)/src,f)\n"; - szTmp += QString("%alias = \"alias(%1::uninstall::uninstallaliases){$lf\"\n") \ - .arg(m_szName); - szTmp += "for(%i=0; %i<$length(%files[]); %i++)\n{\n"; - szTmp += "\tinclude $file.extractpath($0)/src/%files[%i]\n"; - szTmp += "\t%flt = $str.left(%files[%i],$($str.len(%files[%i])-4))\n"; - szTmp += "\t%file = $str.replace(%flt,\"_\",\"::\")\n"; - szTmp += "\t%alias .= \"alias(%file){};$lf\"\n}\n"; - szTmp += QString("\t%alias .= \"alias(%1::uninstall::uninstallfiles){};$lf\"\n") \ - .arg(m_szName); - szTmp += QString("\t%alias .= \"alias(%1::uninstall::uninstallaliases){};$lf\"\n") \ - .arg(m_szName); - szTmp += "%alias .= \"}\"\n"; - szTmp += "eval %alias\n\n"; -#endif - - // install.kvs: include initialization file - szTmp += "# Include initialization file\n"; - szTmp += "include \"init.kvs\" %mypath\n\n"; - - // Put the install.kvs in the buffer - QByteArray buffer; - buffer.append(szTmp.toUtf8()); - - // We don't need to check dir existance since it was checked just before - QDir addon(m_szDirPath); - - // Open file for writing - QFile installer(addon.filePath("install.kvs")); - if(!installer.open(QIODevice::WriteOnly)) - { - *pszError = __tr2qs_ctx("Cannot open file for writing.","addon"); - return false; - } - - // Write the buffer to the file descriptor - if(installer.write(buffer) == -1) - { - *pszError = __tr2qs_ctx("Cannot write to the file descriptor.","addon"); - return false; - } - - return true; -} -#endif - - -bool KviPackAddonDialog::packAddon() -{ - // Get data from registered fields - m_szAuthor = field("packageAuthor").toString(); - m_szName = field("packageName").toString(); - m_szVersion = field("packageVersion").toString(); - m_szDescription = field("packageDescription").toString(); - m_szMinVersion = field("packageMinVersion").toString(); - m_szIcon = field("packageIcon").toString(); - m_szDirPath = field("packageDirPath").toString(); - m_szSavePath = field("packageSavePath").toString(); - - // Check the addon tree - QString szError, szWarning; - - if(!checkDirTree(&szError,&szWarning)) - { - QMessageBox::critical(this, - __tr2qs_ctx("Addon Packaging Error","addon"), - szError,QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton - ); - return false; - } - - if(szWarning != "") - { - QMessageBox::warning(this, - __tr2qs_ctx("Addon Packaging Warning","addon"), - szWarning,QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton - ); - } - - // Raise the files summary dialog - m_pPackAddonSummaryFilesWidget = new KviPackAddonSummaryFilesWidget(this); - m_pPackAddonSummaryFilesWidget->setPath(m_szDirPath); - if(m_pPackAddonSummaryFilesWidget->exec() == QDialog::Rejected) - { - delete m_pPackAddonSummaryFilesWidget; - return false; - } - - - QString szTmp; - szTmp = QDateTime::currentDateTime().toString(); - - KviPackageWriter pw; - pw.addInfoField("PackageType","AddonPack"); - pw.addInfoField("AddonPackVersion",KVI_CURRENT_ADDONS_ENGINE_VERSION); - pw.addInfoField("Name",m_szName); - pw.addInfoField("Version",m_szVersion); - pw.addInfoField("Author",m_szAuthor); - pw.addInfoField("Description",m_szDescription); - pw.addInfoField("Date",szTmp); - pw.addInfoField("Application","KVIrc " KVI_VERSION "." KVI_SOURCES_DATE); - - QPixmap pix(m_szIcon); - if(!pix.isNull()) - { - QByteArray * pba = new QByteArray(); - QBuffer bufferz(pba,0); - - bufferz.open(QIODevice::WriteOnly); - pix.save(&bufferz,"PNG"); - bufferz.close(); - pw.addInfoField("Image",pba); - } - - QDir dir(m_szDirPath); - QFileInfoList ls = dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::Readable | QDir::NoSymLinks | QDir::NoDotAndDotDot); - - if(ls.isEmpty()) - { - szTmp = __tr2qs_ctx("Packaging failed","addon"); - szTmp += ": "; - szTmp += __tr2qs_ctx("The package file list is empty","addon"); - QMessageBox::critical(this,__tr2qs_ctx("Export Addon - KVIrc","addon"),szTmp,QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton); - return false; - } - - for(QFileInfoList::Iterator it = ls.begin();it != ls.end();++it) - { - const QFileInfo &inf = *it; - - if(inf.isDir()) - { - if(!pw.addDirectory(inf.absoluteFilePath(),QString("%1/").arg(inf.fileName()))) - { - QString szTmp = __tr2qs_ctx("Packaging failed","addon"); - szTmp += ": "; - szTmp += pw.lastError(); - QMessageBox::critical(this,__tr2qs_ctx("Export Addon - KVIrc","addon"),szTmp,QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton); - return false; - } - - continue; - } - - // must be a file - if(!pw.addFile(inf.absoluteFilePath(),inf.fileName())) - { - szTmp = __tr2qs_ctx("Packaging failed","addon"); - szTmp += ": "; - szTmp += pw.lastError(); - QMessageBox::critical(this,__tr2qs_ctx("Export Addon - KVIrc","addon"),szTmp,QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton); - return false; - } - } - - - // Create the addon package - if(m_szSavePath.isEmpty()) - { - m_szSavePath = QDir::homePath(); - KviQString::ensureLastCharIs(m_szSavePath,QChar(KVI_PATH_SEPARATOR_CHAR)); - m_szSavePath += m_szName; - m_szSavePath += "-"; - m_szSavePath += m_szVersion; - m_szSavePath += KVI_FILEEXTENSION_ADDONPACKAGE; - } - - if(!pw.pack(m_szSavePath)) - { - szTmp = __tr2qs_ctx("Packaging failed","addon"); - szTmp += ": "; - szTmp += pw.lastError(); - QMessageBox::critical(this,__tr2qs_ctx("Export Addon - KVIrc","addon"),szTmp,QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton); - return false; - } - - - QMessageBox::information(this,__tr2qs_ctx("Export Addon - KVIrc","addon"),__tr2qs("Package saved successfully in ") + m_szSavePath,QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton); - - return true; -} - - -KviPackAddonInfoPackageWidget::KviPackAddonInfoPackageWidget(KviPackAddonDialog * pParent) -: QWizardPage(pParent) -{ - setObjectName("addon_package_info_page"); - setTitle(__tr2qs_ctx("Package Information","addon")); - setSubTitle(__tr2qs_ctx("Here you need to provide information about you (the packager) and a short description of the package you're creating.","addon")); - - QGridLayout * pLayout = new QGridLayout(this); - - QLabel * pLabel = new QLabel(this); - pLabel->setText(__tr2qs_ctx("Package &Author:","addon")); - pLayout->addWidget(pLabel,0,0); - - m_pPackageAuthorEdit = new QLineEdit(this); - m_pPackageAuthorEdit->setText(__tr2qs_ctx("Your name here","addon")); - pLabel->setBuddy(m_pPackageAuthorEdit); - pLayout->addWidget(m_pPackageAuthorEdit,0,1); - - pLabel = new QLabel(this); - pLabel->setText(__tr2qs_ctx("Package &Name:","addon")); - pLayout->addWidget(pLabel,1,0); - - m_pPackageNameEdit = new QLineEdit(this); - m_pPackageNameEdit->setText(__tr2qs_ctx("No spaces allowed, like MyAddon","addon")); - pLabel->setBuddy(m_pPackageNameEdit); - pLayout->addWidget(m_pPackageNameEdit,1,1); - - pLabel = new QLabel(this); - pLabel->setText(__tr2qs_ctx("Package &Version:","addon")); - pLayout->addWidget(pLabel,2,0); - - m_pPackageVersionEdit = new QLineEdit(this); - m_pPackageVersionEdit->setText(__tr2qs_ctx("Version in the form x.y[.z], like 1.0 or 2.0.3","addon")); - pLabel->setBuddy(m_pPackageVersionEdit); - pLayout->addWidget(m_pPackageVersionEdit,2,1); - - pLabel = new QLabel(this); - pLabel->setText(__tr2qs_ctx("Package &Description:","addon")); - pLayout->addWidget(pLabel,3,0); - - m_pPackageDescriptionEdit = new QLineEdit(this); - m_pPackageDescriptionEdit->setText(QString()); - pLabel->setBuddy(m_pPackageDescriptionEdit); - pLayout->addWidget(m_pPackageDescriptionEdit,3,1); - - pLabel = new QLabel(this); - pLabel->setText(__tr2qs_ctx("Minimum &KVIrc Version:","addon")); - pLayout->addWidget(pLabel,4,0); - - m_pPackageMinVersionEdit = new QLineEdit(this); - m_pPackageMinVersionEdit->setText(KVI_VERSION); - pLabel->setBuddy(m_pPackageMinVersionEdit); - pLayout->addWidget(m_pPackageMinVersionEdit,4,1); - - // Store data in the fields - registerField("packageAuthor*",m_pPackageAuthorEdit); - registerField("packageName*",m_pPackageNameEdit); - registerField("packageVersion*",m_pPackageVersionEdit); - registerField("packageDescription*",m_pPackageDescriptionEdit); - registerField("packageMinVersion",m_pPackageMinVersionEdit); -} - -KviPackAddonInfoPackageWidget::~KviPackAddonInfoPackageWidget() -{ -} - - -KviPackAddonFileSelectionWidget::KviPackAddonFileSelectionWidget(KviPackAddonDialog * pParent) -: QWizardPage(pParent) -{ - setObjectName("addon_package_file_page"); - setTitle(__tr2qs_ctx("Package Files","addon")); - setSubTitle(__tr2qs_ctx("Here you need to select the directory where the addon files are.","addon")); - - QVBoxLayout * pLayout = new QVBoxLayout(this); - - // Select source directory - m_pDirPathSelector = new KviDirectorySelector(this,__tr2qs_ctx("Select the source directory:","addon"),&m_szDirPath,true,KviFileSelector::VerticalLayout); - pLayout->addWidget(m_pDirPathSelector); - - // Select addon icon - m_pPackageIconEdit = new KviFileSelector(this,__tr2qs_ctx("Select the icon file:","addon"),&m_szPackageIcon,true,KviFileSelector::VerticalLayout,KVI_FILTER_IMAGE); - pLayout->addWidget(m_pPackageIconEdit); - - // Store data in the fields - registerField("packageDirPath*",m_pDirPathSelector); - registerField("packageIcon*",m_pPackageIconEdit); -} - -KviPackAddonFileSelectionWidget::~KviPackAddonFileSelectionWidget() -{ -} - - -KviPackAddonSaveSelectionWidget::KviPackAddonSaveSelectionWidget(KviPackAddonDialog * pParent) -: QWizardPage(pParent) -{ - setObjectName("addon_package_save_page"); - setTitle(__tr2qs_ctx("Save Package","addon")); - setSubTitle(__tr2qs_ctx("Here you need to provide the path where to save the addon package","addon")); - - QVBoxLayout * pLayout = new QVBoxLayout(this); - - // Select save path - m_pSavePathSelector = new KviFileSelector( - this, - __tr2qs_ctx("Select save path:","addon"), - &m_szFilePath, - true, - KviFileSelector::ChooseSaveFileName | KviFileSelector::VerticalLayout, - KVI_FILTER_ADDON - ); - pLayout->addWidget(m_pSavePathSelector); - - // Store data in the fields - registerField("packageSavePath*",m_pSavePathSelector); -} - -KviPackAddonSaveSelectionWidget::~KviPackAddonSaveSelectionWidget() -{ -} - -void KviPackAddonSaveSelectionWidget::initializePage() -{ - // Get data from registered fields - QString szName = field("packageName").toString(); - QString szVersion = field("packageVersion").toString(); - - // Create addon name - QString szSavePath = QDir::homePath(); - KviQString::ensureLastCharIs(szSavePath,QChar(KVI_PATH_SEPARATOR_CHAR)); - szSavePath += szName; - szSavePath += "-"; - szSavePath += szVersion; - szSavePath += KVI_FILEEXTENSION_ADDONPACKAGE; - m_pSavePathSelector->setTmpFile(szSavePath); -} - - -KviPackAddonSummaryInfoWidget::KviPackAddonSummaryInfoWidget(KviPackAddonDialog * pParent) -: QWizardPage(pParent) -{ - setObjectName("addon_package_summary_info_page"); - setTitle(__tr2qs_ctx("Final Information","addon")); - setSubTitle(__tr2qs_ctx("Here there are the information you provided. If these information are correct, hit the \"Finish\" button to complete the packaging operations.","addon")); - - QVBoxLayout * pLayout = new QVBoxLayout(this); - m_pLabelInfo = new QLabel(this); - pLayout->addWidget(m_pLabelInfo); -} - -KviPackAddonSummaryInfoWidget::~KviPackAddonSummaryInfoWidget() -{ -} - -void KviPackAddonSummaryInfoWidget::initializePage() -{ - // Get data from registered fields - QString szAuthor = field("packageAuthor").toString(); - QString szName = field("packageName").toString(); - QString szVersion = field("packageVersion").toString(); - QString szDescription = field("packageDescription").toString(); - QString szMinVersion = field("packageMinVersion").toString(); - QString szIcon = field("packageIcon").toString(); - QString szDirPath = field("packageDirPath").toString(); - QString szSavePath = field("packageSavePath").toString(); - - QString szText = __tr2qs_ctx("This is what I will check for:","addon"); - szText += "

"; - szText += __tr2qs_ctx("Package Author","addon"); - szText += ": "; - szText += szAuthor; - szText += "
"; - szText += __tr2qs_ctx("Package Name","addon"); - szText += ": "; - szText += szName; - szText += "
"; - szText += __tr2qs_ctx("Package Version","addon"); - szText += ": "; - szText += szVersion; - szText += "
"; - szText += __tr2qs_ctx("Package Description","addon"); - szText += ": "; - szText += szDescription; - szText += "
"; - szText += __tr2qs_ctx("Minimum KVIrc Version","addon"); - szText += ": "; - szText += szMinVersion; - szText += "
"; - szText += __tr2qs_ctx("Icon File","addon"); - szText += ": "; - szText += szIcon; - szText += "
"; - szText += __tr2qs_ctx("Source Directory","addon"); - szText += ": "; - szText += szDirPath; - szText += "
"; - szText += __tr2qs_ctx("Save Path","addon"); - szText += ": "; - szText += szSavePath; - - m_pLabelInfo->setText(szText); -} - - -KviPackAddonSummaryFilesWidget::KviPackAddonSummaryFilesWidget(KviPackAddonDialog * pParent) -: QDialog(pParent) -{ - setObjectName("addon_package_summary_file_dialog"); - setWindowTitle(__tr2qs_ctx("File Summary","addon")); - setWindowModality(Qt::WindowModal); - setModal(true); - - QVBoxLayout * pLayout = new QVBoxLayout(this); - - QLabel * pLabel = new QLabel(this); - pLabel->setText(__tr2qs_ctx("Here there are the files I found in the directories you provided.\nIf these and the information showed in the previous page are correct, hit the \"Finish\" button to complete\nthe packaging operations.","addon")); - pLayout->addWidget(pLabel); - - m_pFiles = new QTextEdit(this); - m_pFiles->setReadOnly(true); - pLayout->addWidget(m_pFiles); - - KviTalHBox * pBox = new KviTalHBox(this); - QPushButton * pCancel = new QPushButton(pBox); - pCancel->setText(__tr2qs_ctx("Cancel","addon")); - connect(pCancel,SIGNAL(clicked()),this,SLOT(reject())); - - QPushButton * pAccept = new QPushButton(pBox); - pAccept->setText(__tr2qs_ctx("Finish","addon")); - connect(pAccept,SIGNAL(clicked()),this,SLOT(accept())); - pLayout->addWidget(pBox); -} - -KviPackAddonSummaryFilesWidget::~KviPackAddonSummaryFilesWidget() -{ -} - -void KviPackAddonSummaryFilesWidget::accept() -{ - QDialog::accept(); -} - -void KviPackAddonSummaryFilesWidget::reject() -{ - QDialog::reject(); -} - -void KviPackAddonSummaryFilesWidget::showEvent(QShowEvent *) -{ - QStringList list; - - QDirIterator it(m_szPath,QDir::AllEntries | QDir::NoDotAndDotDot,QDirIterator::Subdirectories); - - // Iterate through the addon dir and its subdirs - while(it.hasNext()) - { - QString szStr = it.next(); - if(!szStr.contains("/.")) - list.append(szStr); - } - - // QDirIterator does not support sorting, so do it manually - list.sort(); - - m_pFiles->setPlainText(list.join("\n")); -} diff --git a/src/modules/addon/packaddondialog.h b/src/modules/addon/packaddondialog.h deleted file mode 100644 index bf5dbf1ba..000000000 --- a/src/modules/addon/packaddondialog.h +++ /dev/null @@ -1,252 +0,0 @@ -#ifndef _PACKADDONDIALOG_H_ -#define _PACKADDONDIALOG_H_ -//============================================================================= -// -// File : packaddondialog.h -// Creation date : Sat 03 May 2008 01:40:44 by Elvio Basello -// -// This file is part of the KVIrc IRC Client distribution -// Copyright (C) 2008-2009 Elvio Basello -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -/** -* \file packaddondialog.h -* \author Elvio Basello -* \brief Addon package creator -* -* This set of classes allow users to create addon for KVIrc in a standard -* distributable *.kva packages. -*/ - -#include "kvi_settings.h" -#include "KviPointerList.h" -#include "KviSelectors.h" - -#include -#include - -class QTextEdit; -class QLineEdit; -class QLabel; - -class KviPackageWriter; - -class KviPackAddonInfoPackageWidget; -class KviPackAddonFileSelectionWidget; -class KviPackAddonSaveSelectionWidget; -class KviPackAddonSummaryInfoWidget; -class KviPackAddonSummaryFilesWidget; - -/** -* \class KviPackAddonDialog -* \brief Wizard for addon creation -*/ -class KviPackAddonDialog : public QWizard -{ - Q_OBJECT -public: - /** - * \brief Creates the wizard object - * \param pParent The parent widget - * \return KviPackAddonDialog - */ - KviPackAddonDialog(QWidget * pParent); - - /** - * \brief Destroys the wizard object - */ - ~KviPackAddonDialog(); -protected: - KviPackAddonInfoPackageWidget * m_pPackAddonInfoPackageWidget; - KviPackAddonFileSelectionWidget * m_pPackAddonFileSelectionWidget; - KviPackAddonSaveSelectionWidget * m_pPackAddonSaveSelectionWidget; - KviPackAddonSummaryInfoWidget * m_pPackAddonSummaryInfoWidget; - KviPackAddonSummaryFilesWidget * m_pPackAddonSummaryFilesWidget; - QString m_szAuthor; - QString m_szName; - QString m_szVersion; - QString m_szDescription; - QString m_szMinVersion; - QString m_szIcon; - QString m_szDirPath; - QString m_szSavePath; -protected: - /** - * \brief Runs the packAddon() function and closes the wizard - * \return void - */ - virtual void accept(); - - /** - * \brief Creates the addon package - * \return bool - */ - bool packAddon(); - - /** - * \brief Ensures the sources directory is complete - * \param pszError The buffer containing errors - * \param pszWarning The buffer containing warnings - * \return bool - */ - bool checkDirTree(QString * pszError, QString * pszWarning); - - /** - * \brief Creates the installer file - * \param pszError The buffer containing errors - * \return bool - */ - bool createInstaller(QString * pszError); -}; - -/** -* \class KviPackAddonInfoPackageWidget -* \brief Wizard page for addon information -*/ -class KviPackAddonInfoPackageWidget : public QWizardPage -{ - Q_OBJECT -public: - /** - * \brief Create the wizard package info page object - * \param pParent The parent widget - * \return KviPackAddonInfoPackageWidget - */ - KviPackAddonInfoPackageWidget(KviPackAddonDialog * pParent); - - /** - * \brief Destroys the wizard package info page object - */ - ~KviPackAddonInfoPackageWidget(); -protected: - QLineEdit * m_pPackageAuthorEdit; - QLineEdit * m_pPackageNameEdit; - QLineEdit * m_pPackageVersionEdit; - QLineEdit * m_pPackageDescriptionEdit; - QLineEdit * m_pPackageMinVersionEdit; -}; - -/** -* \class KviPackAddonFileSelectionWidget -* \brief Wizard page for directory source selection -*/ -class KviPackAddonFileSelectionWidget : public QWizardPage -{ - Q_OBJECT -public: - /** - * \brief Create the wizard package source dir object - * \param pParent The parent widget - * \return KviPackAddonFileSelectionWidget - */ - KviPackAddonFileSelectionWidget(KviPackAddonDialog * pParent); - - /** - * \brief Destroys the wizard package source dir object - */ - ~KviPackAddonFileSelectionWidget(); -protected: - KviDirectorySelector * m_pDirPathSelector; - KviFileSelector * m_pPackageIconEdit; - QString m_szDirPath; - QString m_szPackageIcon; -}; - -/** -* \class KviPackAddonSaveSelectionWidget -* \brief Wizard page for saving package -*/ -class KviPackAddonSaveSelectionWidget : public QWizardPage -{ - Q_OBJECT -public: - /** - * \brief Create the wizard save page object - * \param pParent The parent widget - * \return KviPackAddonSaveSelectionWidget - */ - KviPackAddonSaveSelectionWidget(KviPackAddonDialog * pParent); - - /** - * \brief Destroys the wizard save page object - */ - ~KviPackAddonSaveSelectionWidget(); -protected: - KviFileSelector * m_pSavePathSelector; - QString m_szFilePath; -protected: - /** - * \brief Perform initial tasks before showing the widget - * \return void - */ - virtual void initializePage(); -}; - -/** -* \class KviPackAddonSummaryInfoWidget -* \brief Wizard page for showing information inserted -*/ -class KviPackAddonSummaryInfoWidget : public QWizardPage -{ - Q_OBJECT -public: - /** - * \brief Create the wizard summary info page object - * \param pParent The parent widget - * \return KviPackAddonSummaryInfoWidget - */ - KviPackAddonSummaryInfoWidget(KviPackAddonDialog * pParent); - - /** - * \brief Destroys the wizard summary info page object - */ - ~KviPackAddonSummaryInfoWidget(); -protected: - QLabel * m_pLabelInfo; - QLabel * m_pLabelAuthor; - QLabel * m_pPackageName; - QLabel * m_pPackageVersion; - QLabel * m_pPackageDescription; -protected: - /** - * \brief Perform initial tasks before showing the widget - * \return void - */ - virtual void initializePage(); -}; - - -class KviPackAddonSummaryFilesWidget : public QDialog -{ - Q_OBJECT -public: - KviPackAddonSummaryFilesWidget(KviPackAddonDialog * pParent); - ~KviPackAddonSummaryFilesWidget(); -protected: - QTextEdit * m_pFiles; - QString m_szPath; -public: - void setPath(QString & szPath){ m_szPath = szPath; }; -protected: - virtual void showEvent(QShowEvent *); -protected slots: - virtual void accept(); - virtual void reject(); -}; - -#endif //!_PACKADDONDIALOG_H_ diff --git a/src/modules/aliaseditor/AliasEditorWindow.cpp b/src/modules/aliaseditor/AliasEditorWindow.cpp new file mode 100644 index 000000000..e53272448 --- /dev/null +++ b/src/modules/aliaseditor/AliasEditorWindow.cpp @@ -0,0 +1,1247 @@ +//============================================================================= +// +// File : AliasEditorWindow.cpp +// Creation date : Mon Dec 23 2002 14:36:18 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the linkss of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include "AliasEditorWindow.h" + +#include "KviIconManager.h" +#include "KviOptions.h" +#include "KviLocale.h" +#include "KviImageDialog.h" +#include "KviConfigurationFile.h" +#include "KviFileDialog.h" +#include "KviFileUtils.h" +#include "KviScriptEditor.h" +#include "kvi_debug.h" +#include "KviApplication.h" +#include "KviMainWindow.h" +#include "KviQString.h" +#include "KviKvsAliasManager.h" +#include "KviFileDialog.h" +#include "KviCommandFormatter.h" +#include "KviModule.h" +#include "KviTalVBox.h" +#include "kvi_fileextensions.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +extern AliasEditorWindow * g_pAliasEditorWindow; +extern KviModule * g_pAliasEditorModule; + + +AliasEditorTreeWidgetItem::AliasEditorTreeWidgetItem(QTreeWidget * pTreeWidget,Type eType,const QString &szName) +: QTreeWidgetItem(pTreeWidget), KviHeapObject(), m_eType(eType), m_pParentItem(0) +{ + setName(szName); + m_cPos=0; + if(eType==AliasEditorTreeWidgetItem::Namespace) setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE)))); + else setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ALIAS)))); +} + +AliasEditorTreeWidgetItem::AliasEditorTreeWidgetItem(AliasEditorTreeWidgetItem * pParentItem,Type eType,const QString &szName) +: QTreeWidgetItem(pParentItem), m_eType(eType), m_pParentItem(pParentItem) +{ + setName(szName); + m_cPos=0; + setFlags(Qt::ItemIsEditable|Qt::ItemIsEnabled|Qt::ItemIsSelectable); + if(eType==AliasEditorTreeWidgetItem::Namespace) setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE)))); + else setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ALIAS)))); +} + +void AliasEditorTreeWidgetItem::setName(const QString &szName) +{ + m_szName = szName; + setText(0,m_szName); +} +void AliasEditorTreeWidgetItem::setType(Type t) +{ + m_eType=t; + if(t==AliasEditorTreeWidgetItem::Namespace) setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE)))); + else setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ALIAS)))); +} + +AliasEditorTreeWidget::AliasEditorTreeWidget(QWidget * par) +: QTreeWidget(par) +{ + setColumnCount (1); + setHeaderLabel(__tr2qs_ctx("Alias","editor")); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setSortingEnabled(true); + setRootIsDecorated(true); + setAnimated(true); +} + +AliasEditorTreeWidget::~AliasEditorTreeWidget() +{ + //remove and delete all items + clear(); +} + + +AliasEditorWidget::AliasEditorWidget(QWidget * par) +: QWidget(par) +{ + m_pAliases=new KviPointerList; + m_pAliases->setAutoDelete(false); + + m_bSaving = false; + m_pLastEditedItem = 0; + m_pLastClickedItem = 0; + m_szDir = QDir::homePath(); + + QGridLayout * l = new QGridLayout(this); + + m_pSplitter = new QSplitter(Qt::Horizontal,this); + m_pSplitter->setChildrenCollapsible(false); + l->addWidget(m_pSplitter,0,0); + + KviTalVBox * box = new KviTalVBox(m_pSplitter); + box->setSpacing(0); + box->setMargin(0); + + m_pTreeWidget = new AliasEditorTreeWidget(box); + + box = new KviTalVBox(m_pSplitter); + KviTalHBox * hbox = new KviTalHBox(box); + hbox->setSpacing(0); + hbox->setMargin(0); + m_pNameLabel = new QLabel(__tr2qs_ctx("No item selected","editor"),hbox); + m_pRenameButton = new QPushButton(__tr2qs_ctx("Rename","editor"),hbox); + m_pRenameButton->setEnabled(false); + connect(m_pRenameButton,SIGNAL(clicked()),this,SLOT(renameItem())); + hbox->setStretchFactor(m_pNameLabel,2); + m_pRenameButton->setToolTip(__tr2qs_ctx("Edit the alias or namespace name","editor")); + m_pEditor = KviScriptEditor::createInstance(box); + m_pEditor->setFocus(); + + connect(m_pEditor,SIGNAL(find(const QString &)),this,SLOT(slotFindWord(const QString &))); + connect(m_pEditor,SIGNAL(replaceAll(const QString &,const QString &)),this,SLOT(slotReplaceAll(const QString &,const QString &))); + + m_pContextPopup = new KviTalPopupMenu(this); + + oneTimeSetup(); + + currentItemChanged(0,0); +} + +AliasEditorWidget::~AliasEditorWidget() +{ + KviScriptEditor::destroyInstance(m_pEditor); + delete m_pAliases; +} + +void AliasEditorWidget::buildFullItemPath(AliasEditorTreeWidgetItem * it,QString &szBuffer) +{ + if (it->isAlias()) it=it->parentItem(); + if (!it) return; + while(it) + { + QString tmp = it->name(); + if(!tmp.isEmpty()) + { + szBuffer.prepend("::"); + szBuffer.prepend(tmp); + } + it = it->parentItem(); + } +} + +QString AliasEditorWidget::buildFullItemName(AliasEditorTreeWidgetItem * it) +{ + if(!it) return QString(); + QString szName = it->name(); + AliasEditorTreeWidgetItem * nit = it->parentItem(); + + while(nit) + { + QString tmp = nit->name(); + if(!tmp.isEmpty()) + { + szName.prepend("::"); + szName.prepend(tmp); + } + nit = nit->parentItem(); + } + return szName; +} + +//FIXME this should be called something like "findNamespace" +AliasEditorTreeWidgetItem * AliasEditorWidget::findTopLevelItem(const QString &szName) +{ + AliasEditorTreeWidgetItem *pItem =0; + for(int i=0;itopLevelItemCount();i++) + { + pItem = (AliasEditorTreeWidgetItem*) m_pTreeWidget->topLevelItem(i); + if (pItem->text(0)==szName && pItem->isNamespace()) + return (AliasEditorTreeWidgetItem*)m_pTreeWidget->topLevelItem(i); + } + return 0; +} + +AliasEditorTreeWidgetItem * AliasEditorWidget::findItem(const QString &szFullName) +{ + QStringList lNamespaces=szFullName.split("::"); + if(!lNamespaces.count()) return 0; + AliasEditorTreeWidgetItem *pItem=findTopLevelItem(lNamespaces.at(0)); + if (!pItem) return 0; + bool bFound; + int i; + int j; + for(i=1;ichildCount();j++) + { + if (KviQString::equalCI(pItem->child(j)->text(0),lNamespaces.at(i))) + { + pItem=( AliasEditorTreeWidgetItem *)pItem->child(j); + bFound=true; + break; + } + } + if (!bFound) return 0; + } + return (AliasEditorTreeWidgetItem *)pItem; +} + + +AliasEditorTreeWidgetItem * AliasEditorWidget::createFullItem(const QString &szFullName) +{ + QStringList lNamespaces=szFullName.split("::"); + if(!lNamespaces.count()) return 0; + if (lNamespaces.count()==1) return new AliasEditorTreeWidgetItem(m_pTreeWidget,AliasEditorTreeWidgetItem::Alias,lNamespaces.at(0)); + AliasEditorTreeWidgetItem *pItem=findTopLevelItem(lNamespaces.at(0)); + if (!pItem) pItem=new AliasEditorTreeWidgetItem(m_pTreeWidget,AliasEditorTreeWidgetItem::Namespace,lNamespaces.at(0)); + bool bFound; + int i; + for(i=1;ichildCount();j++) + { + if (KviQString::equalCI(pItem->child(j)->text(0),lNamespaces.at(i))) + { + pItem=( AliasEditorTreeWidgetItem *)pItem->child(j); + bFound=true; + break; + } + } + if (!bFound) + pItem=new AliasEditorTreeWidgetItem(pItem,AliasEditorTreeWidgetItem::Namespace,lNamespaces.at(i)); + } + return new AliasEditorTreeWidgetItem(pItem,AliasEditorTreeWidgetItem::Alias,lNamespaces.at(i)); +} + + +void AliasEditorWidget::oneTimeSetup() +{ + KviPointerHashTable * a = KviKvsAliasManager::instance()->aliasDict(); + if(!a)return; + + KviPointerHashTableIterator it(*a); + + AliasEditorTreeWidgetItem * item; + while(it.current()) + { + KviKvsScript * alias = it.current(); + item = createFullItem(alias->name()); + item->setBuffer(alias->code()); + m_pAliases->append(item); + ++it; + } + + connect(m_pTreeWidget,SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),this,SLOT(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *))); + m_pTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_pTreeWidget,SIGNAL(customContextMenuRequested(const QPoint &)),this,SLOT(customContextMenuRequested(const QPoint &))); + connect(m_pTreeWidget,SIGNAL(itemChanged(QTreeWidgetItem *,int)),this,SLOT(itemRenamed(QTreeWidgetItem *,int))); + connect(KviKvsAliasManager::instance(),SIGNAL(aliasRefresh(const QString &)),this,SLOT(aliasRefresh(const QString &))); + m_pTreeWidget->sortItems(0,Qt::AscendingOrder); +} + +void AliasEditorWidget::aliasRefresh(const QString &szName) +{ + if(m_bSaving) + return; + AliasEditorTreeWidgetItem * item=0; + KviKvsScript * alias = KviKvsAliasManager::instance()->aliasDict()->find(szName); + + // search for old alias with same name + KviPointerList l; + l.setAutoDelete(false); + appendAllItems(&l,AliasEditorTreeWidgetItem::Alias); + for(AliasEditorTreeWidgetItem * it = l.first();it;it = l.next()) + { + if (KviQString::equalCI(buildFullItemName(it),szName)) + { + item=it; + break; + } + } + if(!item) + { + item = createFullItem(szName); + m_pAliases->append(item); + } + + if(item!=m_pLastEditedItem) + { + item->setBuffer(alias->code()); + return; + } + if( + QMessageBox::warning(0,__tr2qs_ctx("OverWrite Current Alias","editor"), + __tr2qs_ctx("An external script has changed the alias you are currently editing. Do you want to accept the external changes?","editor"), + QMessageBox::Yes,QMessageBox::No|QMessageBox::Default|QMessageBox::Escape) != QMessageBox::Yes + ) + return; + item->setBuffer(alias->code()); + m_pEditor->setText(alias->code()); +} +void AliasEditorWidget::itemRenamed(QTreeWidgetItem *it,int col) +{ + if(it!=m_pLastEditedItem) return; + + ((AliasEditorTreeWidgetItem *)it)->setName(it->text(col)); + QString szNam = buildFullItemName((AliasEditorTreeWidgetItem *)it); + QString szLabelText; + if(((AliasEditorTreeWidgetItem *)it)->isNamespace()) + szLabelText = __tr2qs_ctx("Namespace","editor"); + else + szLabelText = __tr2qs_ctx("Alias","editor"); + szLabelText += ": "; + szLabelText += szNam; + szLabelText += ""; + m_pNameLabel->setText(szLabelText); +} + + + +bool AliasEditorWidget::hasSelectedItems() + { + return m_pTreeWidget->selectedItems().count()?1:0; +} + +bool AliasEditorWidget::itemExists(QTreeWidgetItem *pSearchFor) +{ + if(!pSearchFor)return false; + if (m_pAliases->findRef((AliasEditorTreeWidgetItem*) pSearchFor)!=-1) return true; + else return false; +} + +void AliasEditorWidget::appendAllItems(KviPointerList * l,AliasEditorTreeWidgetItem::Type eType) +{ + for (int i=0;itopLevelItemCount();i++) + { + if (((AliasEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i))->type()==eType) + { + l->append(((AliasEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i))); + } else { + appendAllItemsRecursive(l,m_pTreeWidget->topLevelItem(i),eType); + } + } +} + +void AliasEditorWidget::appendAllItemsRecursive(KviPointerList * l,QTreeWidgetItem * pStartFrom,AliasEditorTreeWidgetItem::Type eType) +{ + for (int i=0;ichildCount();i++) + { + if (((AliasEditorTreeWidgetItem *)pStartFrom->child(i))->type()==eType) + { + l->append((AliasEditorTreeWidgetItem *)pStartFrom->child(i)); + } else { + appendAllItemsRecursive(l,pStartFrom->child(i),eType); + } + } +} + +bool AliasEditorWidget::aliasExists(QString &szFullItemName) +{ + KviPointerList l; + l.setAutoDelete(false); + appendAllItems(&l,AliasEditorTreeWidgetItem::Alias); + for(AliasEditorTreeWidgetItem * it = l.first();it;it = l.next()) + { + if (KviQString::equalCI(buildFullItemName(it),szFullItemName)) + { + return true; + } + } + return false; +} + +bool AliasEditorWidget::namespaceExists(QString &szFullItemName) +{ + KviPointerList l; + l.setAutoDelete(false); + + appendAllItems(&l,AliasEditorTreeWidgetItem::Namespace); + for(AliasEditorTreeWidgetItem * it = l.first();it;it = l.next()) + { + if (KviQString::equalCI(buildFullItemName(it),szFullItemName)) + { + return true; + } + } + return false; +} +void AliasEditorWidget::renameItem() +{ + if(!m_pLastEditedItem)return; + //if(itemExists(m_pLastEditedItem))return; // dead ? + QString szName = buildFullItemName(m_pLastEditedItem); + QString szNewName; + + bool bAlias = m_pLastEditedItem->isAlias(); + + if(bAlias) + szNewName = askForAliasName(__tr2qs_ctx("Rename Alias","editor"),__tr2qs_ctx("Please enter the new name for the alias","editor"),szName); + else + szNewName = askForNamespaceName(__tr2qs_ctx("Rename Namespace","editor"),__tr2qs_ctx("Please enter the new name for the namespace","editor"),szName); + if(szNewName.isEmpty())return; + + if(szName == szNewName)return; + + // check if there is already an alias with this name + if (bAlias) + { + if (aliasExists(szNewName)) + { + g_pAliasEditorModule->lock(); + QMessageBox::information(this, + __tr2qs_ctx("Alias already exists","editor"), + __tr2qs_ctx("This name is already in use. Please choose another one.","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + g_pAliasEditorModule->unlock(); + return; + } + } else { + // check if there is already a namespace with this name + if (namespaceExists(szNewName)) + { + g_pAliasEditorModule->lock(); + QMessageBox::information(this, + __tr2qs_ctx("Namespace already exists","editor"), + __tr2qs_ctx("This name is already in use. Please choose another one.","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + g_pAliasEditorModule->unlock(); + return; + } + } + + QString szCode; + int pntCursor; + if(bAlias) + { + m_pEditor->getText(szCode); + pntCursor = m_pEditor->getCursor(); + } + QList lChildren= m_pLastEditedItem->takeChildren(); + bool bYesToAll = true; + removeItem(m_pLastEditedItem,&bYesToAll,true); + + m_pLastEditedItem = 0; // make sure it's true (but it already should be because of removeItem()) + m_pLastClickedItem = 0; // make sure it's true (but it already should be because of removeItem()) + AliasEditorTreeWidgetItem * pItem = createFullItem(szNewName); + if(bAlias) + { + pItem->setBuffer(szCode); + pItem->setCursorPosition(pntCursor); + + } else { + for(int i=0;isetParentItem(pItem); + pItem->insertChild(pItem->childCount(),lChildren.at(i)); + } + + } + activateItem(pItem); + m_pAliases->append(pItem); +} + +// warning: this saves ONLY the body, not the name! +// the name is changed explicitly with renameItem(), when needed + +void AliasEditorWidget::saveLastEditedItem() +{ + if(!m_pLastEditedItem) + return; + if(!itemExists(m_pLastEditedItem) || !m_pEditor->isModified() || m_pLastEditedItem->isNamespace()) + return; + ((AliasEditorTreeWidgetItem *)m_pLastEditedItem)->setCursorPosition(m_pEditor->getCursor()); + QString newCode; + m_pEditor->getText(newCode); + ((AliasEditorTreeWidgetItem *)m_pLastEditedItem)->setBuffer(newCode); +} + +void AliasEditorWidget::currentItemChanged(QTreeWidgetItem *it,QTreeWidgetItem *) +{ + saveLastEditedItem(); + m_pLastEditedItem = (AliasEditorTreeWidgetItem *)it; + + if(!m_pLastEditedItem) + { + m_pNameLabel->setText(__tr2qs_ctx("No item selected","editor")); + m_pRenameButton->setEnabled(false); + m_pEditor->setText(""); + m_pEditor->setEnabled(false); + return; + } + + QString szNam = buildFullItemName(m_pLastEditedItem); + if(m_pLastEditedItem->isNamespace()) + { + QString szLabelText = __tr2qs_ctx("Namespace","editor"); + szLabelText += ": "; + szLabelText += szNam; + szLabelText += ""; + m_pNameLabel->setText(szLabelText); + m_pRenameButton->setEnabled(true); + m_pEditor->setText(""); + m_pEditor->setEnabled(false); + m_pTreeWidget->setFocus(); + return; + } + + QString szLabelText = __tr2qs_ctx("Alias","editor"); + szLabelText += ": "; + szLabelText += szNam; + szLabelText += ""; + m_pNameLabel->setText(szLabelText); + m_pRenameButton->setEnabled(true); + m_pEditor->setText(((AliasEditorTreeWidgetItem *)it)->buffer()); + + m_pEditor->setFocus(); + m_pEditor->setCursorPosition(((AliasEditorTreeWidgetItem *)it)->cursorPosition()); + m_pEditor->setEnabled(true); +} + + +void AliasEditorWidget::customContextMenuRequested(const QPoint pnt) +{ + m_pContextPopup->clear(); + m_pLastClickedItem = (AliasEditorTreeWidgetItem *)m_pTreeWidget->itemAt(pnt); + + int id; + + m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_ALIAS)), + __tr2qs_ctx("Add Alias","editor"), + this,SLOT(newAlias())); + + m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_ALIAS)), + __tr2qs_ctx("Add Namespace","editor"), + this,SLOT(newNamespace())); + + bool bHasItems = m_pTreeWidget->topLevelItemCount(); + bool bHasSelected = hasSelectedItems(); + + m_pContextPopup->insertSeparator(); + + id = m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)), + __tr2qs_ctx("Remove Selected","editor"), + this,SLOT(removeSelectedItems())); + m_pContextPopup->setItemEnabled(id,bHasSelected); + + m_pContextPopup->insertSeparator(); + + m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)), + __tr2qs_ctx("Export Selected...","editor"), + this,SLOT(exportSelected())); + m_pContextPopup->setItemEnabled(id,bHasSelected); + + m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)), + __tr2qs_ctx("Export Selected in singles files...","editor"), + this,SLOT(exportSelectedSepFiles())); + + m_pContextPopup->setItemEnabled(id,bHasSelected); + + m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)), + __tr2qs_ctx("Export All...","editor"), + this,SLOT(exportAll())); + m_pContextPopup->setItemEnabled(id,bHasItems); + + m_pContextPopup->insertSeparator(); + + m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_SEARCH)), + __tr2qs_ctx("Find In Aliases...","editor"), + this,SLOT(slotFind())); + m_pContextPopup->setItemEnabled(id,bHasItems); + + m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE)), + __tr2qs_ctx("Collapse All Namespaces","editor"), + this,SLOT(slotCollapseNamespaces())); + + m_pContextPopup->setItemEnabled(id,bHasItems); + m_pContextPopup->popup( m_pTreeWidget->mapToGlobal(pnt)); +} + +void AliasEditorWidget::searchReplace(const QString &szSearch,bool bReplace,const QString &szReplace) +{ + for(unsigned int i=0;icount();i++) + { + AliasEditorTreeWidgetItem *pItem=m_pAliases->at(i); + if(pItem->buffer().indexOf(szSearch,0,Qt::CaseInsensitive) != -1) + { + pItem->setBackground(0, QColor(255,0,0,128)); + if (bReplace) ((QString &)pItem->buffer()).replace(szSearch,szReplace,Qt::CaseInsensitive); + openParentItems(pItem); + } else { + pItem->setBackground(0, QColor(255,255,255)); + } + } +} + +void AliasEditorWidget::slotFind() +{ + + g_pAliasEditorModule->lock(); + bool bOk; + + QString szSearch = QInputDialog::getText(this, + __tr2qs_ctx("Find In Aliases","editor"), + __tr2qs_ctx("Please enter the text to be searched for. The matching aliases will be highlighted.","editor"), + QLineEdit::Normal, + "", + &bOk); + + g_pAliasEditorModule->unlock(); + if(!bOk)return; + if(szSearch.isEmpty())return; + m_pEditor->setFindText(szSearch); + searchReplace(szSearch); +} + +void AliasEditorWidget::slotFindWord(const QString &szSearch) +{ + m_pEditor->setFindText(szSearch); +} + +void AliasEditorWidget::recursiveCollapseNamespaces(AliasEditorTreeWidgetItem * it) +{ + if(!it)return; + for (int i=0;ichildCount();i++) + { + if(it->child(i)->childCount()) + { + it->child(i)->setExpanded(false); + recursiveCollapseNamespaces((AliasEditorTreeWidgetItem *)it->child(i)); + } + } +} + +void AliasEditorWidget::slotCollapseNamespaces() +{ + for (int i=0;itopLevelItemCount();i++) + { + if (m_pTreeWidget->topLevelItem(i)->childCount()){ + m_pTreeWidget->topLevelItem(i)->setExpanded(false); + recursiveCollapseNamespaces((AliasEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i)); + } + } +} + +void AliasEditorWidget::slotReplaceAll(const QString &szFind,const QString &szReplace) +{ + m_pEditor->setFindText(szReplace); + searchReplace(szFind,true,szReplace); +} + +void AliasEditorWidget::getExportAliasBuffer(QString &buffer,AliasEditorTreeWidgetItem * it) +{ + QString szBuf = it->buffer(); + KviCommandFormatter::blockFromBuffer(szBuf); + QString szNam = buildFullItemName(it); + + buffer = "alias("; + buffer += szNam; + buffer += ")\n"; + buffer += szBuf; + buffer += "\n"; +} + +void AliasEditorWidget::exportAll() +{ + exportAliases(false); +} + +void AliasEditorWidget::exportSelectedSepFiles() +{ + exportAliases (true,true); +} + +void AliasEditorWidget::exportSelected() +{ + exportAliases(true); +} + +void AliasEditorWidget::exportSelectionInSinglesFiles(KviPointerList *l) +{ + if(!m_szDir.endsWith(QString(KVI_PATH_SEPARATOR)))m_szDir += KVI_PATH_SEPARATOR; + if (!l->first()) + { + g_pAliasEditorModule->lock(); + QMessageBox::warning(this,__tr2qs_ctx("Alias Export","editor"),__tr2qs_ctx("There is no selection!","editor"),__tr2qs_ctx("OK","editor")); + g_pAliasEditorModule->unlock(); + return; + } + g_pAliasEditorModule->lock(); + + if(!KviFileDialog::askForDirectoryName(m_szDir,__tr2qs_ctx("Choose a Directory - KVIrc","editor"),m_szDir)){ + g_pAliasEditorModule->unlock(); + return; + } + + if(!m_szDir.endsWith(QString(KVI_PATH_SEPARATOR)))m_szDir += KVI_PATH_SEPARATOR; + + bool bReplaceAll=false; + + for(AliasEditorTreeWidgetItem * it = l->first();it;it = l->next()) + { + QString tmp; + getExportAliasBuffer(tmp,it); + QString szFileName=buildFullItemName(it); + szFileName += ".kvs"; + szFileName.replace("::","_"); + QString szCompletePath=m_szDir+szFileName; + if (KviFileUtils::fileExists(szCompletePath) && !bReplaceAll) + { + QString szMsg; + KviQString::sprintf(szMsg,__tr2qs_ctx("The file \"%Q\" exists. Do you want to replace it ?","editor"),&szFileName); + int ret = QMessageBox::question(this,__tr2qs_ctx("Replace file","editor"),szMsg,__tr2qs_ctx("Yes","editor"),__tr2qs_ctx("Yes to All","editor"),__tr2qs_ctx("No","editor")); + if (ret!=2) + { + KviFileUtils::writeFile(szCompletePath,tmp); + if (ret==1) bReplaceAll=true; + } + } else { + KviFileUtils::writeFile(szCompletePath,tmp); + } + } + g_pAliasEditorModule->unlock(); +} + +void AliasEditorWidget::exportAliases(bool bSelectedOnly,bool bSingleFiles) +{ + saveLastEditedItem(); + + KviPointerList l; + l.setAutoDelete(false); + + if (bSelectedOnly) appendSelectedAliasItems(&l); + if (bSingleFiles) + { + exportSelectionInSinglesFiles(&l); + return; + } + QString szOut; + int count; + + if (bSelectedOnly) + { + count=l.count(); + buildAliasesFile(&l,szOut); + } else { + count=m_pAliases->count(); + buildAliasesFile(m_pAliases,szOut); + } + QString szNameFile; + if(szOut.isEmpty()) + { + g_pAliasEditorModule->lock(); + QMessageBox::warning(this,__tr2qs_ctx("Alias Export","editor"),__tr2qs_ctx("The exported file would be empty: cowardly refusing to write it","editor"),__tr2qs_ctx("OK","editor")); + g_pAliasEditorModule->unlock(); + return; + } + + QString szName = m_szDir; + + if(!szName.endsWith(QString(KVI_PATH_SEPARATOR)))szName += KVI_PATH_SEPARATOR; + QString szFile; + g_pAliasEditorModule->lock(); + + if (count==1) + { + QString tmp=buildFullItemName(l.at(0)); + szNameFile = tmp.replace("::","_"); + } else { + szNameFile="aliases"; + } + szName += szNameFile; + szName += ".kvs"; + if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs_ctx("Choose a Filename - KVIrc","editor"),szName,KVI_FILTER_SCRIPT,false,true,true)) + { + g_pAliasEditorModule->unlock(); + return; + } + m_szDir=QFileInfo(szFile).absolutePath(); + g_pAliasEditorModule->unlock(); + + if(!KviFileUtils::writeFile(szFile,szOut)) + { + g_pAliasEditorModule->lock(); + QMessageBox::warning(this,__tr2qs_ctx("Write Failed - KVIrc","editor"),__tr2qs_ctx("Unable to write to the alias file.","editor"),__tr2qs_ctx("OK","editor")); + g_pAliasEditorModule->unlock(); + } +} +void AliasEditorWidget::buildAliasesFile(KviPointerList *l, QString & szBuffer) +{ + for(AliasEditorTreeWidgetItem * it = l->first();it;it = l->next()) + { + QString tmp; + getExportAliasBuffer(tmp,it); + szBuffer += tmp; + szBuffer += "\n"; + } +} + +void AliasEditorWidget::saveProperties(KviConfigurationFile *cfg) +{ + cfg->writeEntry("Sizes",m_pSplitter->sizes()); + QString szName; + if(m_pLastEditedItem) + szName = buildFullItemName(m_pLastEditedItem); + cfg->writeEntry("LastAlias",szName); +} + +void AliasEditorWidget::loadProperties(KviConfigurationFile *cfg) +{ + QList def; + def.append(20); + def.append(80); + m_pSplitter->setSizes(cfg->readIntListEntry("Sizes",def)); + QString tmp = cfg->readEntry("LastAlias",QString()); + + AliasEditorTreeWidgetItem * it = findItem(tmp); + activateItem(it); +} + +void AliasEditorWidget::appendSelectedAliasItems(KviPointerList * l) +{ + QList list=m_pTreeWidget->selectedItems(); + for(int i=0;iisAlias()) + { + l->append((AliasEditorTreeWidgetItem *)list.at(i)); + } else { + appendSelectedAliasItemsRecursive(l,list.at(i)); + } + } +} +void AliasEditorWidget::appendSelectedAliasItemsRecursive(KviPointerList * l,QTreeWidgetItem * pStartFrom) +{ + for (int i=0;ichildCount();i++) + { + if (((AliasEditorTreeWidgetItem *)pStartFrom->child(i))->isAlias()) + l->append(((AliasEditorTreeWidgetItem *)pStartFrom->child(i))); + else + appendSelectedAliasItemsRecursive(l,pStartFrom->child(i)); + } +} + + +void AliasEditorWidget::appendSelectedItems(KviPointerList * l) +{ + QList list=m_pTreeWidget->selectedItems(); + for(int i=0;iappend((AliasEditorTreeWidgetItem *)list.at(i)); + /* if (!((AliasEditorTreeWidgetItem *)list.at(i))->isAlias()) + appendSelectedAliasItemsRecursive(l,list.at(i));*/ + } + +} +void AliasEditorWidget::appendSelectedItemsRecursive(KviPointerList * l,QTreeWidgetItem * pStartFrom) +{ + for (int i=0;ichildCount();i++) + { + l->append(((AliasEditorTreeWidgetItem *)pStartFrom->child(i))); + if (!((AliasEditorTreeWidgetItem *)pStartFrom->child(i))->isAlias()) + appendSelectedAliasItemsRecursive(l,pStartFrom->child(i)); + } +} + +void AliasEditorWidget::removeItemChildren(AliasEditorTreeWidgetItem *it) +{ + while(it->childCount() > 0) + { + AliasEditorTreeWidgetItem * pChild = (AliasEditorTreeWidgetItem *)(it->child(0)); + if(pChild->childCount()) + removeItemChildren(pChild); + delete pChild; + m_pAliases->removeRef(pChild); + } +} + +bool AliasEditorWidget::removeItem(AliasEditorTreeWidgetItem *it,bool * pbYesToAll,bool) +{ + if(!it)return true; + QString szMsg; + QString szName = it->name(); + + if(!*pbYesToAll) + { + if(it->isAlias()) + KviQString::sprintf(szMsg,__tr2qs_ctx("Do you really want to remove the alias \"%Q\" ?","editor"),&szName); + else { + KviQString::sprintf(szMsg,__tr2qs_ctx("Do you really want to remove the namespace \"%Q\" ?","editor"),&szName); + szMsg += "
"; + szMsg += __tr2qs_ctx("Please note that all the children items will be deleted too.","editor"); + } + + g_pAliasEditorModule->lock(); + int ret = QMessageBox::question(this,__tr2qs_ctx("Remove item","editor"),szMsg,__tr2qs_ctx("Yes","editor"),__tr2qs_ctx("Yes to All","editor"),__tr2qs_ctx("No","editor")); + g_pAliasEditorModule->unlock(); + switch(ret) + { + case 0: + // nothing + break; + case 1: + *pbYesToAll = true; + break; + default: + return false; + break; + } + } + + if(it == m_pLastEditedItem) + m_pLastEditedItem = 0; + if(it == m_pLastClickedItem) + m_pLastClickedItem = 0; + if (it->childCount()) + removeItemChildren(it); + delete it; + m_pAliases->removeRef(it); + return true; +} + +void AliasEditorWidget::removeSelectedItems() +{ + KviPointerList l; + l.setAutoDelete(false); + appendSelectedItems(&l); + bool bYesToAll = false; + for(AliasEditorTreeWidgetItem *it = l.first();it;it = l.next()) + { + if(!removeItem(it,&bYesToAll,false))return; + } +} + +QString AliasEditorWidget::askForAliasName(const QString &szAction,const QString &szText,const QString &szInitialText) +{ + bool bOk = false; + QString szNewName; + while(szNewName.isEmpty()) + { + g_pAliasEditorModule->lock(); + szNewName = QInputDialog::getText(this, + szAction, + szText, + QLineEdit::Normal, + szInitialText, + &bOk); + g_pAliasEditorModule->unlock(); + if(!bOk)return QString(); + if(szNewName.isEmpty()) + { + g_pAliasEditorModule->lock(); + QMessageBox::warning(this, + __tr2qs_ctx("Missing Alias Name","editor"), + __tr2qs_ctx("You must specify a valid name for the alias","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + g_pAliasEditorModule->unlock(); + continue; + } + + // we allow only [\w:]+ + QRegExp re("[\\w:]+"); + if(!re.exactMatch(szNewName)) + { + g_pAliasEditorModule->lock(); + QMessageBox::information(this, + __tr2qs_ctx("Bad Alias Name","editor"), + __tr2qs_ctx("Alias names can contain only letters, digits, underscores and '::' namespace separators","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + g_pAliasEditorModule->unlock(); + szNewName = ""; + continue; + } + // make sure that we have only doubled "::" and not ":" or ":::..." + QString tmp = szNewName; + tmp.replace("::","@"); // @ is not allowed by the rule above + if(tmp.indexOf(":",Qt::CaseInsensitive) != -1) + { + g_pAliasEditorModule->lock(); + QMessageBox::information(this, + __tr2qs_ctx("Bad Alias Name","editor"), + __tr2qs_ctx("Stray ':' character in alias name: did you mean ...:: ?","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + g_pAliasEditorModule->unlock(); + szNewName = ""; + continue; + } + if(tmp.indexOf("@@",Qt::CaseInsensitive) != -1) + { + g_pAliasEditorModule->lock(); + QMessageBox::information(this, + __tr2qs_ctx("Bad Alias Name","editor"), + __tr2qs_ctx("Found an empty namespace in alias name","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + g_pAliasEditorModule->unlock(); + szNewName = ""; + continue; + } + } + return szNewName; +} + +QString AliasEditorWidget::askForNamespaceName(const QString &szAction,const QString &szText,const QString &szInitialText) +{ + bool bOk = false; + QString szNewName; + while(szNewName.isEmpty()) + { + g_pAliasEditorModule->lock(); + szNewName = QInputDialog::getText(this, + szAction, + szText, + QLineEdit::Normal, + szInitialText, + &bOk); + g_pAliasEditorModule->unlock(); + if(!bOk)return QString(); + if(szNewName.isEmpty()) + { + g_pAliasEditorModule->lock(); + QMessageBox::warning(this, + __tr2qs_ctx("Missing Namespace Name","editor"), + __tr2qs_ctx("You must specify a valid name for the namespace","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + g_pAliasEditorModule->unlock(); + continue; + } + + // we allow only [\w:]+ + QRegExp re("[\\w:]+"); + if(!re.exactMatch(szNewName)) + { + g_pAliasEditorModule->lock(); + QMessageBox::information(this, + __tr2qs_ctx("Bad Namespace Name","editor"), + __tr2qs_ctx("Namespace names can contain only letters, digits, underscores and '::' namespace separators","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + g_pAliasEditorModule->unlock(); + szNewName = ""; + continue; + } + // make sure that we have only doubled "::" and not ":" or ":::..." + QString tmp = szNewName; + tmp.replace("::","@"); // @ is not allowed by the rule above + if(tmp.indexOf(":",Qt::CaseInsensitive) != -1) + { + g_pAliasEditorModule->lock(); + QMessageBox::information(this, + __tr2qs_ctx("Bad Namespace Name","editor"), + __tr2qs_ctx("Stray ':' character in namespace name: did you mean ...:: ?","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + g_pAliasEditorModule->unlock(); + szNewName = ""; + continue; + } + if(tmp.indexOf("@@",Qt::CaseInsensitive) != -1) + { + g_pAliasEditorModule->lock(); + QMessageBox::information(this, + __tr2qs_ctx("Bad Namespace Name","editor"), + __tr2qs_ctx("Found an empty namespace in namespace name","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + g_pAliasEditorModule->unlock(); + szNewName = ""; + continue; + } + } + return szNewName; +} + +void AliasEditorWidget::openParentItems(QTreeWidgetItem * it) +{ + if(it->parent()) + { + it->parent()->setExpanded(true); + openParentItems(it->parent()); + } +} + +void AliasEditorWidget::activateItem(QTreeWidgetItem * it) +{ + if (!it) return; + openParentItems(it); + m_pTreeWidget->setCurrentItem(it); +} +void AliasEditorWidget::newAlias() +{ + QString szNewName = askForAliasName(__tr2qs_ctx("Add Alias","editor"),__tr2qs_ctx("Please enter the name for the new alias","editor"),"myfunction"); + if(szNewName.isEmpty())return; + newItem(szNewName,AliasEditorTreeWidgetItem::Alias); +} + +void AliasEditorWidget::newNamespace() +{ + QString szName = askForNamespaceName(__tr2qs_ctx("Add Namespace","editor"),__tr2qs_ctx("Please enter the name for the new namespace","editor"),"mynamespace"); + if(szName.isEmpty())return; + newItem(szName,AliasEditorTreeWidgetItem::Namespace); +} + +void AliasEditorWidget::newItem(QString &szName,AliasEditorTreeWidgetItem::Type eType) +{ + if(m_pLastClickedItem) + if(!itemExists(m_pLastClickedItem)) m_pLastClickedItem=0; + if(m_pLastClickedItem) buildFullItemPath(m_pLastClickedItem,szName); + int idx=1; + QString szTmp; + if(findItem(szName)) szName.append("1"); + while(findItem(szName)) + { + szTmp.setNum(idx); + szName.chop(szTmp.length()); + szName.append(szTmp); + idx++; + } + AliasEditorTreeWidgetItem * it; + it=createFullItem(szName); + it->setType(eType); + m_pAliases->append(it); + activateItem(it); +} + +void AliasEditorWidget::commit() +{ + m_bSaving = true; + saveLastEditedItem(); + KviKvsAliasManager::instance()->clear(); + for(unsigned int i=0;icount();i++) + { + QString szName = buildFullItemName(m_pAliases->at(i)); + KviKvsScript * a = new KviKvsScript(szName,m_pAliases->at(i)->buffer()); + KviKvsAliasManager::instance()->add(szName,a); + } + g_pApp->saveAliases(); + m_bSaving = false; +} + + +AliasEditorWindow::AliasEditorWindow(KviMainWindow * lpFrm) +: KviWindow(KVI_WINDOW_TYPE_SCRIPTEDITOR,lpFrm,"aliaseditor",0) +{ + g_pAliasEditorWindow = this; + + setFixedCaption(__tr2qs_ctx("Alias Editor","editor")); + + QGridLayout * g = new QGridLayout(); + + m_pEditor = new AliasEditorWidget(this); + g->addWidget(m_pEditor,0,0,1,4); + + QPushButton * btn = new QPushButton(__tr2qs_ctx("&OK","editor"),this); + connect(btn,SIGNAL(clicked()),this,SLOT(okClicked())); + btn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT))); + g->addWidget(btn,1,1); + + btn = new QPushButton(__tr2qs_ctx("&Apply","editor"),this); + connect(btn,SIGNAL(clicked()),this,SLOT(applyClicked())); + btn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT))); + g->addWidget(btn,1,2); + + btn = new QPushButton(__tr2qs_ctx("Cancel","editor"),this); + connect(btn,SIGNAL(clicked()),this,SLOT(cancelClicked())); + btn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD))); + g->addWidget(btn,1,3); + + g->setRowStretch(0,1); + g->setColumnStretch(0,1); + setLayout(g); +} + +AliasEditorWindow::~AliasEditorWindow() +{ + g_pAliasEditorWindow = 0; +} + +void AliasEditorWindow::okClicked() +{ + m_pEditor->commit(); + close(); +} + +void AliasEditorWindow::applyClicked() +{ + m_pEditor->commit(); +} + +void AliasEditorWindow::cancelClicked() +{ + close(); +} + +QPixmap * AliasEditorWindow::myIconPtr() +{ + return g_pIconManager->getSmallIcon(KVI_SMALLICON_ALIAS); +} + +void AliasEditorWindow::getConfigGroupName(QString &szName) +{ + szName = "aliaseditor"; +} + +void AliasEditorWindow::saveProperties(KviConfigurationFile *cfg) +{ + m_pEditor->saveProperties(cfg); +} + +void AliasEditorWindow::loadProperties(KviConfigurationFile *cfg) +{ + m_pEditor->loadProperties(cfg); +} diff --git a/src/modules/aliaseditor/AliasEditorWindow.h b/src/modules/aliaseditor/AliasEditorWindow.h new file mode 100644 index 000000000..a571562f6 --- /dev/null +++ b/src/modules/aliaseditor/AliasEditorWindow.h @@ -0,0 +1,190 @@ +#ifndef _ALIASEDITOR_H_ +#define _ALIASEDITOR_H_ +//============================================================================= +// +// File : AliasEditorWindow.h +// Creation date : Mon Dec 23 2002 14:35:55 CEST by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the linkss of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviWindow.h" +#include "KviCString.h" +#include "KviPointerList.h" +#include "KviTalPopupMenu.h" +#include "KviHeapObject.h" + +#include +#include +#include +#include +#include +#include + + +class QSplitter; +class KviScriptEditor; + + + +class AliasEditorTreeWidgetItem : public QTreeWidgetItem, public KviHeapObject +{ +public: + enum Type { Alias, Namespace }; +public: + AliasEditorTreeWidgetItem(QTreeWidget * pTreeWidget,Type eType,const QString &szName); + AliasEditorTreeWidgetItem(AliasEditorTreeWidgetItem * pParentItem,Type eType,const QString &szName); + ~AliasEditorTreeWidgetItem(){}; +protected: + Type m_eType; + AliasEditorTreeWidgetItem * m_pParentItem; + QString m_szName; + QString m_szBuffer; + int m_cPos; +public: + inline const QString & name(){ return m_szName; }; + void setName(const QString &szName); + inline Type type(){ return m_eType; }; + void setType(Type t); + inline bool isAlias(){ return m_eType == Alias; }; + inline bool isNamespace(){ return m_eType == Namespace; }; + void setParentItem(AliasEditorTreeWidgetItem* it){ m_pParentItem=it; }; + AliasEditorTreeWidgetItem * parentItem(){ return m_pParentItem; }; + inline void setBuffer(const QString &szBuffer){ m_szBuffer = szBuffer; }; + inline const QString & buffer(){ return m_szBuffer; }; + inline const int & cursorPosition(){return m_cPos; }; + + void setCursorPosition(const int &cPos){ m_cPos = cPos; }; +}; + + + +class AliasEditorTreeWidget : public QTreeWidget +{ + Q_OBJECT +public: + AliasEditorTreeWidget(QWidget*); + ~AliasEditorTreeWidget(); +}; + +class AliasEditorWidget : public QWidget +{ + Q_OBJECT +public: + AliasEditorWidget(QWidget * par); + ~AliasEditorWidget(); +public: + KviScriptEditor * m_pEditor; + AliasEditorTreeWidget * m_pTreeWidget; + QLabel * m_pNameLabel; + QPushButton * m_pRenameButton; + AliasEditorTreeWidgetItem * m_pLastEditedItem; + AliasEditorTreeWidgetItem * m_pLastClickedItem; + KviTalPopupMenu * m_pContextPopup; + QSplitter * m_pSplitter; + QString m_szDir; + bool m_bSaving; +public: + //bool modified(){ return m_bModified; }; + void commit(); + void exportAliases(bool,bool=false); + void exportSelectionInSinglesFiles(KviPointerList *l); + + void saveProperties(KviConfigurationFile *); + void loadProperties(KviConfigurationFile *); + static void splitFullAliasOrNamespaceName(const QString &szFullName,QStringList &lNamespaces,QString &szName); +protected slots: + void currentItemChanged(QTreeWidgetItem *it,QTreeWidgetItem *); + void renameItem(); + void newAlias(); + void customContextMenuRequested(const QPoint pnt); + void newNamespace(); + void newItem(QString &szName,AliasEditorTreeWidgetItem::Type eType); + + void exportAll(); + void exportSelectedSepFiles(); + void exportSelected(); + + void removeSelectedItems(); + void slotFind(); + void slotCollapseNamespaces(); + void slotFindWord(const QString &); + void slotReplaceAll(const QString &before,const QString &after); + void itemRenamed(QTreeWidgetItem *it,int col); + void aliasRefresh(const QString &szName); + +protected: + KviPointerList *m_pAliases; + void recursiveCollapseNamespaces(AliasEditorTreeWidgetItem * it); + void searchReplace(const QString &szSearch,bool bReplace=false,const QString &szReplace="n"); + + void getExportAliasBuffer(QString &buffer,AliasEditorTreeWidgetItem * it); + void oneTimeSetup(); + void saveLastEditedItem(); + void getUniqueItemName(AliasEditorTreeWidgetItem *item,QString &buffer,AliasEditorTreeWidgetItem::Type eType); + void appendSelectedAliasItems(KviPointerList * l); + void appendSelectedAliasItemsRecursive(KviPointerList * l,QTreeWidgetItem * pStartFrom); + void appendSelectedItems(KviPointerList * l); + void appendSelectedItemsRecursive(KviPointerList * l,QTreeWidgetItem * pStartFrom); + + void openParentItems(QTreeWidgetItem * it); + void activateItem(QTreeWidgetItem * it); + + bool removeItem(AliasEditorTreeWidgetItem *it,bool * pbYesToAll,bool bDeleteEmptyTree); + void removeItemChildren(AliasEditorTreeWidgetItem *it); + + QString askForAliasName(const QString &szAction,const QString &szText,const QString &szInitialText); + QString askForNamespaceName(const QString &szAction,const QString &szText,const QString &szInitialText); +// + bool itemExists(QTreeWidgetItem *pSearchFor); + bool namespaceExists(QString &szFullItemName); + bool aliasExists(QString &szFullItemName); + void appendAllItems(KviPointerList * l,AliasEditorTreeWidgetItem::Type); + void appendAllItemsRecursive(KviPointerList * l,QTreeWidgetItem * pStartFrom,AliasEditorTreeWidgetItem::Type); + bool hasSelectedItems(); + void buildAliasesFile(KviPointerList *l, QString & szBuffer); + + void buildFullItemPath(AliasEditorTreeWidgetItem * it,QString &szBuffer); + AliasEditorTreeWidgetItem * findTopLevelItem(const QString &szName); + AliasEditorTreeWidgetItem * createFullItem(const QString &szFullName); + AliasEditorTreeWidgetItem * findItem(const QString &szName); + QString buildFullItemName(AliasEditorTreeWidgetItem * it); +}; + + +class AliasEditorWindow : public KviWindow +{ + Q_OBJECT +public: + AliasEditorWindow(KviMainWindow * lpFrm); + ~AliasEditorWindow(); +protected: + AliasEditorWidget * m_pEditor; +protected: + virtual QPixmap * myIconPtr(); + virtual void getConfigGroupName(QString &szName); + virtual void saveProperties(KviConfigurationFile *); + virtual void loadProperties(KviConfigurationFile *); +protected slots: + void cancelClicked(); + void okClicked(); + void applyClicked(); +}; + +#endif //_ALIASEDITOR_H_ diff --git a/src/modules/aliaseditor/CMakeLists.txt b/src/modules/aliaseditor/CMakeLists.txt index 2b0c789a8..10f2ee102 100644 --- a/src/modules/aliaseditor/CMakeLists.txt +++ b/src/modules/aliaseditor/CMakeLists.txt @@ -1,12 +1,12 @@ # CMakeLists for src/modules/aliaseditor SET(kvialiaseditor_MOC_HDRS - aliaseditor.h + AliasEditorWindow.h ) SET(kvialiaseditor_SRCS libkvialiaseditor.cpp - aliaseditor.cpp + AliasEditorWindow.cpp ) # After this call, files will be moc'ed to moc_kvi_*.cpp diff --git a/src/modules/aliaseditor/aliaseditor.cpp b/src/modules/aliaseditor/aliaseditor.cpp deleted file mode 100644 index 3fe332576..000000000 --- a/src/modules/aliaseditor/aliaseditor.cpp +++ /dev/null @@ -1,1247 +0,0 @@ -//============================================================================= -// -// File : aliaseditor.cpp -// Creation date : Mon Dec 23 2002 14:36:18 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the linkss of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - - -#include "aliaseditor.h" - -#include "KviIconManager.h" -#include "KviOptions.h" -#include "KviLocale.h" -#include "KviImageDialog.h" -#include "KviConfigurationFile.h" -#include "KviFileDialog.h" -#include "KviFileUtils.h" -#include "KviScriptEditor.h" -#include "kvi_debug.h" -#include "KviApplication.h" -#include "KviMainWindow.h" -#include "KviQString.h" -#include "KviKvsAliasManager.h" -#include "KviFileDialog.h" -#include "KviCommandFormatter.h" -#include "KviModule.h" -#include "KviTalVBox.h" -#include "kvi_fileextensions.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -extern KviAliasEditorWindow * g_pAliasEditorWindow; -extern KviModule * g_pAliasEditorModule; - - -KviAliasEditorTreeWidgetItem::KviAliasEditorTreeWidgetItem(QTreeWidget * pTreeWidget,Type eType,const QString &szName) -: QTreeWidgetItem(pTreeWidget), KviHeapObject(), m_eType(eType), m_pParentItem(0) -{ - setName(szName); - m_cPos=0; - if(eType==KviAliasEditorTreeWidgetItem::Namespace) setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE)))); - else setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ALIAS)))); -} - -KviAliasEditorTreeWidgetItem::KviAliasEditorTreeWidgetItem(KviAliasEditorTreeWidgetItem * pParentItem,Type eType,const QString &szName) -: QTreeWidgetItem(pParentItem), m_eType(eType), m_pParentItem(pParentItem) -{ - setName(szName); - m_cPos=0; - setFlags(Qt::ItemIsEditable|Qt::ItemIsEnabled|Qt::ItemIsSelectable); - if(eType==KviAliasEditorTreeWidgetItem::Namespace) setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE)))); - else setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ALIAS)))); -} - -void KviAliasEditorTreeWidgetItem::setName(const QString &szName) -{ - m_szName = szName; - setText(0,m_szName); -} -void KviAliasEditorTreeWidgetItem::setType(Type t) -{ - m_eType=t; - if(t==KviAliasEditorTreeWidgetItem::Namespace) setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE)))); - else setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ALIAS)))); -} - -KviAliasEditorTreeWidget::KviAliasEditorTreeWidget(QWidget * par) -: QTreeWidget(par) -{ - setColumnCount (1); - setHeaderLabel(__tr2qs_ctx("Alias","editor")); - setSelectionMode(QAbstractItemView::ExtendedSelection); - setSortingEnabled(true); - setRootIsDecorated(true); - setAnimated(true); -} - -KviAliasEditorTreeWidget::~KviAliasEditorTreeWidget() -{ - //remove and delete all items - clear(); -} - - -KviAliasEditor::KviAliasEditor(QWidget * par) -: QWidget(par) -{ - m_pAliases=new KviPointerList; - m_pAliases->setAutoDelete(false); - - m_bSaving = false; - m_pLastEditedItem = 0; - m_pLastClickedItem = 0; - m_szDir = QDir::homePath(); - - QGridLayout * l = new QGridLayout(this); - - m_pSplitter = new QSplitter(Qt::Horizontal,this); - m_pSplitter->setChildrenCollapsible(false); - l->addWidget(m_pSplitter,0,0); - - KviTalVBox * box = new KviTalVBox(m_pSplitter); - box->setSpacing(0); - box->setMargin(0); - - m_pTreeWidget = new KviAliasEditorTreeWidget(box); - - box = new KviTalVBox(m_pSplitter); - KviTalHBox * hbox = new KviTalHBox(box); - hbox->setSpacing(0); - hbox->setMargin(0); - m_pNameLabel = new QLabel(__tr2qs_ctx("No item selected","editor"),hbox); - m_pRenameButton = new QPushButton(__tr2qs_ctx("Rename","editor"),hbox); - m_pRenameButton->setEnabled(false); - connect(m_pRenameButton,SIGNAL(clicked()),this,SLOT(renameItem())); - hbox->setStretchFactor(m_pNameLabel,2); - m_pRenameButton->setToolTip(__tr2qs_ctx("Edit the alias or namespace name","editor")); - m_pEditor = KviScriptEditor::createInstance(box); - m_pEditor->setFocus(); - - connect(m_pEditor,SIGNAL(find(const QString &)),this,SLOT(slotFindWord(const QString &))); - connect(m_pEditor,SIGNAL(replaceAll(const QString &,const QString &)),this,SLOT(slotReplaceAll(const QString &,const QString &))); - - m_pContextPopup = new KviTalPopupMenu(this); - - oneTimeSetup(); - - currentItemChanged(0,0); -} - -KviAliasEditor::~KviAliasEditor() -{ - KviScriptEditor::destroyInstance(m_pEditor); - delete m_pAliases; -} - -void KviAliasEditor::buildFullItemPath(KviAliasEditorTreeWidgetItem * it,QString &szBuffer) -{ - if (it->isAlias()) it=it->parentItem(); - if (!it) return; - while(it) - { - QString tmp = it->name(); - if(!tmp.isEmpty()) - { - szBuffer.prepend("::"); - szBuffer.prepend(tmp); - } - it = it->parentItem(); - } -} - -QString KviAliasEditor::buildFullItemName(KviAliasEditorTreeWidgetItem * it) -{ - if(!it) return QString(); - QString szName = it->name(); - KviAliasEditorTreeWidgetItem * nit = it->parentItem(); - - while(nit) - { - QString tmp = nit->name(); - if(!tmp.isEmpty()) - { - szName.prepend("::"); - szName.prepend(tmp); - } - nit = nit->parentItem(); - } - return szName; -} - -//FIXME this should be called something like "findNamespace" -KviAliasEditorTreeWidgetItem * KviAliasEditor::findTopLevelItem(const QString &szName) -{ - KviAliasEditorTreeWidgetItem *pItem =0; - for(int i=0;itopLevelItemCount();i++) - { - pItem = (KviAliasEditorTreeWidgetItem*) m_pTreeWidget->topLevelItem(i); - if (pItem->text(0)==szName && pItem->isNamespace()) - return (KviAliasEditorTreeWidgetItem*)m_pTreeWidget->topLevelItem(i); - } - return 0; -} - -KviAliasEditorTreeWidgetItem * KviAliasEditor::findItem(const QString &szFullName) -{ - QStringList lNamespaces=szFullName.split("::"); - if(!lNamespaces.count()) return 0; - KviAliasEditorTreeWidgetItem *pItem=findTopLevelItem(lNamespaces.at(0)); - if (!pItem) return 0; - bool bFound; - int i; - int j; - for(i=1;ichildCount();j++) - { - if (KviQString::equalCI(pItem->child(j)->text(0),lNamespaces.at(i))) - { - pItem=( KviAliasEditorTreeWidgetItem *)pItem->child(j); - bFound=true; - break; - } - } - if (!bFound) return 0; - } - return (KviAliasEditorTreeWidgetItem *)pItem; -} - - -KviAliasEditorTreeWidgetItem * KviAliasEditor::createFullItem(const QString &szFullName) -{ - QStringList lNamespaces=szFullName.split("::"); - if(!lNamespaces.count()) return 0; - if (lNamespaces.count()==1) return new KviAliasEditorTreeWidgetItem(m_pTreeWidget,KviAliasEditorTreeWidgetItem::Alias,lNamespaces.at(0)); - KviAliasEditorTreeWidgetItem *pItem=findTopLevelItem(lNamespaces.at(0)); - if (!pItem) pItem=new KviAliasEditorTreeWidgetItem(m_pTreeWidget,KviAliasEditorTreeWidgetItem::Namespace,lNamespaces.at(0)); - bool bFound; - int i; - for(i=1;ichildCount();j++) - { - if (KviQString::equalCI(pItem->child(j)->text(0),lNamespaces.at(i))) - { - pItem=( KviAliasEditorTreeWidgetItem *)pItem->child(j); - bFound=true; - break; - } - } - if (!bFound) - pItem=new KviAliasEditorTreeWidgetItem(pItem,KviAliasEditorTreeWidgetItem::Namespace,lNamespaces.at(i)); - } - return new KviAliasEditorTreeWidgetItem(pItem,KviAliasEditorTreeWidgetItem::Alias,lNamespaces.at(i)); -} - - -void KviAliasEditor::oneTimeSetup() -{ - KviPointerHashTable * a = KviKvsAliasManager::instance()->aliasDict(); - if(!a)return; - - KviPointerHashTableIterator it(*a); - - KviAliasEditorTreeWidgetItem * item; - while(it.current()) - { - KviKvsScript * alias = it.current(); - item = createFullItem(alias->name()); - item->setBuffer(alias->code()); - m_pAliases->append(item); - ++it; - } - - connect(m_pTreeWidget,SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),this,SLOT(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *))); - m_pTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu); - connect(m_pTreeWidget,SIGNAL(customContextMenuRequested(const QPoint &)),this,SLOT(customContextMenuRequested(const QPoint &))); - connect(m_pTreeWidget,SIGNAL(itemChanged(QTreeWidgetItem *,int)),this,SLOT(itemRenamed(QTreeWidgetItem *,int))); - connect(KviKvsAliasManager::instance(),SIGNAL(aliasRefresh(const QString &)),this,SLOT(aliasRefresh(const QString &))); - m_pTreeWidget->sortItems(0,Qt::AscendingOrder); -} - -void KviAliasEditor::aliasRefresh(const QString &szName) -{ - if(m_bSaving) - return; - KviAliasEditorTreeWidgetItem * item=0; - KviKvsScript * alias = KviKvsAliasManager::instance()->aliasDict()->find(szName); - - // search for old alias with same name - KviPointerList l; - l.setAutoDelete(false); - appendAllItems(&l,KviAliasEditorTreeWidgetItem::Alias); - for(KviAliasEditorTreeWidgetItem * it = l.first();it;it = l.next()) - { - if (KviQString::equalCI(buildFullItemName(it),szName)) - { - item=it; - break; - } - } - if(!item) - { - item = createFullItem(szName); - m_pAliases->append(item); - } - - if(item!=m_pLastEditedItem) - { - item->setBuffer(alias->code()); - return; - } - if( - QMessageBox::warning(0,__tr2qs_ctx("OverWrite Current Alias","editor"), - __tr2qs_ctx("An external script has changed the alias you are currently editing. Do you want to accept the external changes?","editor"), - QMessageBox::Yes,QMessageBox::No|QMessageBox::Default|QMessageBox::Escape) != QMessageBox::Yes - ) - return; - item->setBuffer(alias->code()); - m_pEditor->setText(alias->code()); -} -void KviAliasEditor::itemRenamed(QTreeWidgetItem *it,int col) -{ - if(it!=m_pLastEditedItem) return; - - ((KviAliasEditorTreeWidgetItem *)it)->setName(it->text(col)); - QString szNam = buildFullItemName((KviAliasEditorTreeWidgetItem *)it); - QString szLabelText; - if(((KviAliasEditorTreeWidgetItem *)it)->isNamespace()) - szLabelText = __tr2qs_ctx("Namespace","editor"); - else - szLabelText = __tr2qs_ctx("Alias","editor"); - szLabelText += ": "; - szLabelText += szNam; - szLabelText += ""; - m_pNameLabel->setText(szLabelText); -} - - - -bool KviAliasEditor::hasSelectedItems() - { - return m_pTreeWidget->selectedItems().count()?1:0; -} - -bool KviAliasEditor::itemExists(QTreeWidgetItem *pSearchFor) -{ - if(!pSearchFor)return false; - if (m_pAliases->findRef((KviAliasEditorTreeWidgetItem*) pSearchFor)!=-1) return true; - else return false; -} - -void KviAliasEditor::appendAllItems(KviPointerList * l,KviAliasEditorTreeWidgetItem::Type eType) -{ - for (int i=0;itopLevelItemCount();i++) - { - if (((KviAliasEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i))->type()==eType) - { - l->append(((KviAliasEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i))); - } else { - appendAllItemsRecursive(l,m_pTreeWidget->topLevelItem(i),eType); - } - } -} - -void KviAliasEditor::appendAllItemsRecursive(KviPointerList * l,QTreeWidgetItem * pStartFrom,KviAliasEditorTreeWidgetItem::Type eType) -{ - for (int i=0;ichildCount();i++) - { - if (((KviAliasEditorTreeWidgetItem *)pStartFrom->child(i))->type()==eType) - { - l->append((KviAliasEditorTreeWidgetItem *)pStartFrom->child(i)); - } else { - appendAllItemsRecursive(l,pStartFrom->child(i),eType); - } - } -} - -bool KviAliasEditor::aliasExists(QString &szFullItemName) -{ - KviPointerList l; - l.setAutoDelete(false); - appendAllItems(&l,KviAliasEditorTreeWidgetItem::Alias); - for(KviAliasEditorTreeWidgetItem * it = l.first();it;it = l.next()) - { - if (KviQString::equalCI(buildFullItemName(it),szFullItemName)) - { - return true; - } - } - return false; -} - -bool KviAliasEditor::namespaceExists(QString &szFullItemName) -{ - KviPointerList l; - l.setAutoDelete(false); - - appendAllItems(&l,KviAliasEditorTreeWidgetItem::Namespace); - for(KviAliasEditorTreeWidgetItem * it = l.first();it;it = l.next()) - { - if (KviQString::equalCI(buildFullItemName(it),szFullItemName)) - { - return true; - } - } - return false; -} -void KviAliasEditor::renameItem() -{ - if(!m_pLastEditedItem)return; - //if(itemExists(m_pLastEditedItem))return; // dead ? - QString szName = buildFullItemName(m_pLastEditedItem); - QString szNewName; - - bool bAlias = m_pLastEditedItem->isAlias(); - - if(bAlias) - szNewName = askForAliasName(__tr2qs_ctx("Rename Alias","editor"),__tr2qs_ctx("Please enter the new name for the alias","editor"),szName); - else - szNewName = askForNamespaceName(__tr2qs_ctx("Rename Namespace","editor"),__tr2qs_ctx("Please enter the new name for the namespace","editor"),szName); - if(szNewName.isEmpty())return; - - if(szName == szNewName)return; - - // check if there is already an alias with this name - if (bAlias) - { - if (aliasExists(szNewName)) - { - g_pAliasEditorModule->lock(); - QMessageBox::information(this, - __tr2qs_ctx("Alias already exists","editor"), - __tr2qs_ctx("This name is already in use. Please choose another one.","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - g_pAliasEditorModule->unlock(); - return; - } - } else { - // check if there is already a namespace with this name - if (namespaceExists(szNewName)) - { - g_pAliasEditorModule->lock(); - QMessageBox::information(this, - __tr2qs_ctx("Namespace already exists","editor"), - __tr2qs_ctx("This name is already in use. Please choose another one.","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - g_pAliasEditorModule->unlock(); - return; - } - } - - QString szCode; - int pntCursor; - if(bAlias) - { - m_pEditor->getText(szCode); - pntCursor = m_pEditor->getCursor(); - } - QList lChildren= m_pLastEditedItem->takeChildren(); - bool bYesToAll = true; - removeItem(m_pLastEditedItem,&bYesToAll,true); - - m_pLastEditedItem = 0; // make sure it's true (but it already should be because of removeItem()) - m_pLastClickedItem = 0; // make sure it's true (but it already should be because of removeItem()) - KviAliasEditorTreeWidgetItem * pItem = createFullItem(szNewName); - if(bAlias) - { - pItem->setBuffer(szCode); - pItem->setCursorPosition(pntCursor); - - } else { - for(int i=0;isetParentItem(pItem); - pItem->insertChild(pItem->childCount(),lChildren.at(i)); - } - - } - activateItem(pItem); - m_pAliases->append(pItem); -} - -// warning: this saves ONLY the body, not the name! -// the name is changed explicitly with renameItem(), when needed - -void KviAliasEditor::saveLastEditedItem() -{ - if(!m_pLastEditedItem) - return; - if(!itemExists(m_pLastEditedItem) || !m_pEditor->isModified() || m_pLastEditedItem->isNamespace()) - return; - ((KviAliasEditorTreeWidgetItem *)m_pLastEditedItem)->setCursorPosition(m_pEditor->getCursor()); - QString newCode; - m_pEditor->getText(newCode); - ((KviAliasEditorTreeWidgetItem *)m_pLastEditedItem)->setBuffer(newCode); -} - -void KviAliasEditor::currentItemChanged(QTreeWidgetItem *it,QTreeWidgetItem *) -{ - saveLastEditedItem(); - m_pLastEditedItem = (KviAliasEditorTreeWidgetItem *)it; - - if(!m_pLastEditedItem) - { - m_pNameLabel->setText(__tr2qs_ctx("No item selected","editor")); - m_pRenameButton->setEnabled(false); - m_pEditor->setText(""); - m_pEditor->setEnabled(false); - return; - } - - QString szNam = buildFullItemName(m_pLastEditedItem); - if(m_pLastEditedItem->isNamespace()) - { - QString szLabelText = __tr2qs_ctx("Namespace","editor"); - szLabelText += ": "; - szLabelText += szNam; - szLabelText += ""; - m_pNameLabel->setText(szLabelText); - m_pRenameButton->setEnabled(true); - m_pEditor->setText(""); - m_pEditor->setEnabled(false); - m_pTreeWidget->setFocus(); - return; - } - - QString szLabelText = __tr2qs_ctx("Alias","editor"); - szLabelText += ": "; - szLabelText += szNam; - szLabelText += ""; - m_pNameLabel->setText(szLabelText); - m_pRenameButton->setEnabled(true); - m_pEditor->setText(((KviAliasEditorTreeWidgetItem *)it)->buffer()); - - m_pEditor->setFocus(); - m_pEditor->setCursorPosition(((KviAliasEditorTreeWidgetItem *)it)->cursorPosition()); - m_pEditor->setEnabled(true); -} - - -void KviAliasEditor::customContextMenuRequested(const QPoint pnt) -{ - m_pContextPopup->clear(); - m_pLastClickedItem = (KviAliasEditorTreeWidgetItem *)m_pTreeWidget->itemAt(pnt); - - int id; - - m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_ALIAS)), - __tr2qs_ctx("Add Alias","editor"), - this,SLOT(newAlias())); - - m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_ALIAS)), - __tr2qs_ctx("Add Namespace","editor"), - this,SLOT(newNamespace())); - - bool bHasItems = m_pTreeWidget->topLevelItemCount(); - bool bHasSelected = hasSelectedItems(); - - m_pContextPopup->insertSeparator(); - - id = m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)), - __tr2qs_ctx("Remove Selected","editor"), - this,SLOT(removeSelectedItems())); - m_pContextPopup->setItemEnabled(id,bHasSelected); - - m_pContextPopup->insertSeparator(); - - m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)), - __tr2qs_ctx("Export Selected...","editor"), - this,SLOT(exportSelected())); - m_pContextPopup->setItemEnabled(id,bHasSelected); - - m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)), - __tr2qs_ctx("Export Selected in singles files...","editor"), - this,SLOT(exportSelectedSepFiles())); - - m_pContextPopup->setItemEnabled(id,bHasSelected); - - m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)), - __tr2qs_ctx("Export All...","editor"), - this,SLOT(exportAll())); - m_pContextPopup->setItemEnabled(id,bHasItems); - - m_pContextPopup->insertSeparator(); - - m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_SEARCH)), - __tr2qs_ctx("Find In Aliases...","editor"), - this,SLOT(slotFind())); - m_pContextPopup->setItemEnabled(id,bHasItems); - - m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE)), - __tr2qs_ctx("Collapse All Namespaces","editor"), - this,SLOT(slotCollapseNamespaces())); - - m_pContextPopup->setItemEnabled(id,bHasItems); - m_pContextPopup->popup( m_pTreeWidget->mapToGlobal(pnt)); -} - -void KviAliasEditor::searchReplace(const QString &szSearch,bool bReplace,const QString &szReplace) -{ - for(unsigned int i=0;icount();i++) - { - KviAliasEditorTreeWidgetItem *pItem=m_pAliases->at(i); - if(pItem->buffer().indexOf(szSearch,0,Qt::CaseInsensitive) != -1) - { - pItem->setBackground(0, QColor(255,0,0,128)); - if (bReplace) ((QString &)pItem->buffer()).replace(szSearch,szReplace,Qt::CaseInsensitive); - openParentItems(pItem); - } else { - pItem->setBackground(0, QColor(255,255,255)); - } - } -} - -void KviAliasEditor::slotFind() -{ - - g_pAliasEditorModule->lock(); - bool bOk; - - QString szSearch = QInputDialog::getText(this, - __tr2qs_ctx("Find In Aliases","editor"), - __tr2qs_ctx("Please enter the text to be searched for. The matching aliases will be highlighted.","editor"), - QLineEdit::Normal, - "", - &bOk); - - g_pAliasEditorModule->unlock(); - if(!bOk)return; - if(szSearch.isEmpty())return; - m_pEditor->setFindText(szSearch); - searchReplace(szSearch); -} - -void KviAliasEditor::slotFindWord(const QString &szSearch) -{ - m_pEditor->setFindText(szSearch); -} - -void KviAliasEditor::recursiveCollapseNamespaces(KviAliasEditorTreeWidgetItem * it) -{ - if(!it)return; - for (int i=0;ichildCount();i++) - { - if(it->child(i)->childCount()) - { - it->child(i)->setExpanded(false); - recursiveCollapseNamespaces((KviAliasEditorTreeWidgetItem *)it->child(i)); - } - } -} - -void KviAliasEditor::slotCollapseNamespaces() -{ - for (int i=0;itopLevelItemCount();i++) - { - if (m_pTreeWidget->topLevelItem(i)->childCount()){ - m_pTreeWidget->topLevelItem(i)->setExpanded(false); - recursiveCollapseNamespaces((KviAliasEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i)); - } - } -} - -void KviAliasEditor::slotReplaceAll(const QString &szFind,const QString &szReplace) -{ - m_pEditor->setFindText(szReplace); - searchReplace(szFind,true,szReplace); -} - -void KviAliasEditor::getExportAliasBuffer(QString &buffer,KviAliasEditorTreeWidgetItem * it) -{ - QString szBuf = it->buffer(); - KviCommandFormatter::blockFromBuffer(szBuf); - QString szNam = buildFullItemName(it); - - buffer = "alias("; - buffer += szNam; - buffer += ")\n"; - buffer += szBuf; - buffer += "\n"; -} - -void KviAliasEditor::exportAll() -{ - exportAliases(false); -} - -void KviAliasEditor::exportSelectedSepFiles() -{ - exportAliases (true,true); -} - -void KviAliasEditor::exportSelected() -{ - exportAliases(true); -} - -void KviAliasEditor::exportSelectionInSinglesFiles(KviPointerList *l) -{ - if(!m_szDir.endsWith(QString(KVI_PATH_SEPARATOR)))m_szDir += KVI_PATH_SEPARATOR; - if (!l->first()) - { - g_pAliasEditorModule->lock(); - QMessageBox::warning(this,__tr2qs_ctx("Alias Export","editor"),__tr2qs_ctx("There is no selection!","editor"),__tr2qs_ctx("OK","editor")); - g_pAliasEditorModule->unlock(); - return; - } - g_pAliasEditorModule->lock(); - - if(!KviFileDialog::askForDirectoryName(m_szDir,__tr2qs_ctx("Choose a Directory - KVIrc","editor"),m_szDir)){ - g_pAliasEditorModule->unlock(); - return; - } - - if(!m_szDir.endsWith(QString(KVI_PATH_SEPARATOR)))m_szDir += KVI_PATH_SEPARATOR; - - bool bReplaceAll=false; - - for(KviAliasEditorTreeWidgetItem * it = l->first();it;it = l->next()) - { - QString tmp; - getExportAliasBuffer(tmp,it); - QString szFileName=buildFullItemName(it); - szFileName += ".kvs"; - szFileName.replace("::","_"); - QString szCompletePath=m_szDir+szFileName; - if (KviFileUtils::fileExists(szCompletePath) && !bReplaceAll) - { - QString szMsg; - KviQString::sprintf(szMsg,__tr2qs_ctx("The file \"%Q\" exists. Do you want to replace it ?","editor"),&szFileName); - int ret = QMessageBox::question(this,__tr2qs_ctx("Replace file","editor"),szMsg,__tr2qs_ctx("Yes","editor"),__tr2qs_ctx("Yes to All","editor"),__tr2qs_ctx("No","editor")); - if (ret!=2) - { - KviFileUtils::writeFile(szCompletePath,tmp); - if (ret==1) bReplaceAll=true; - } - } else { - KviFileUtils::writeFile(szCompletePath,tmp); - } - } - g_pAliasEditorModule->unlock(); -} - -void KviAliasEditor::exportAliases(bool bSelectedOnly,bool bSingleFiles) -{ - saveLastEditedItem(); - - KviPointerList l; - l.setAutoDelete(false); - - if (bSelectedOnly) appendSelectedAliasItems(&l); - if (bSingleFiles) - { - exportSelectionInSinglesFiles(&l); - return; - } - QString szOut; - int count; - - if (bSelectedOnly) - { - count=l.count(); - buildAliasesFile(&l,szOut); - } else { - count=m_pAliases->count(); - buildAliasesFile(m_pAliases,szOut); - } - QString szNameFile; - if(szOut.isEmpty()) - { - g_pAliasEditorModule->lock(); - QMessageBox::warning(this,__tr2qs_ctx("Alias Export","editor"),__tr2qs_ctx("The exported file would be empty: cowardly refusing to write it","editor"),__tr2qs_ctx("OK","editor")); - g_pAliasEditorModule->unlock(); - return; - } - - QString szName = m_szDir; - - if(!szName.endsWith(QString(KVI_PATH_SEPARATOR)))szName += KVI_PATH_SEPARATOR; - QString szFile; - g_pAliasEditorModule->lock(); - - if (count==1) - { - QString tmp=buildFullItemName(l.at(0)); - szNameFile = tmp.replace("::","_"); - } else { - szNameFile="aliases"; - } - szName += szNameFile; - szName += ".kvs"; - if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs_ctx("Choose a Filename - KVIrc","editor"),szName,KVI_FILTER_SCRIPT,false,true,true)) - { - g_pAliasEditorModule->unlock(); - return; - } - m_szDir=QFileInfo(szFile).absolutePath(); - g_pAliasEditorModule->unlock(); - - if(!KviFileUtils::writeFile(szFile,szOut)) - { - g_pAliasEditorModule->lock(); - QMessageBox::warning(this,__tr2qs_ctx("Write Failed - KVIrc","editor"),__tr2qs_ctx("Unable to write to the alias file.","editor"),__tr2qs_ctx("OK","editor")); - g_pAliasEditorModule->unlock(); - } -} -void KviAliasEditor::buildAliasesFile(KviPointerList *l, QString & szBuffer) -{ - for(KviAliasEditorTreeWidgetItem * it = l->first();it;it = l->next()) - { - QString tmp; - getExportAliasBuffer(tmp,it); - szBuffer += tmp; - szBuffer += "\n"; - } -} - -void KviAliasEditor::saveProperties(KviConfigurationFile *cfg) -{ - cfg->writeEntry("Sizes",m_pSplitter->sizes()); - QString szName; - if(m_pLastEditedItem) - szName = buildFullItemName(m_pLastEditedItem); - cfg->writeEntry("LastAlias",szName); -} - -void KviAliasEditor::loadProperties(KviConfigurationFile *cfg) -{ - QList def; - def.append(20); - def.append(80); - m_pSplitter->setSizes(cfg->readIntListEntry("Sizes",def)); - QString tmp = cfg->readEntry("LastAlias",QString()); - - KviAliasEditorTreeWidgetItem * it = findItem(tmp); - activateItem(it); -} - -void KviAliasEditor::appendSelectedAliasItems(KviPointerList * l) -{ - QList list=m_pTreeWidget->selectedItems(); - for(int i=0;iisAlias()) - { - l->append((KviAliasEditorTreeWidgetItem *)list.at(i)); - } else { - appendSelectedAliasItemsRecursive(l,list.at(i)); - } - } -} -void KviAliasEditor::appendSelectedAliasItemsRecursive(KviPointerList * l,QTreeWidgetItem * pStartFrom) -{ - for (int i=0;ichildCount();i++) - { - if (((KviAliasEditorTreeWidgetItem *)pStartFrom->child(i))->isAlias()) - l->append(((KviAliasEditorTreeWidgetItem *)pStartFrom->child(i))); - else - appendSelectedAliasItemsRecursive(l,pStartFrom->child(i)); - } -} - - -void KviAliasEditor::appendSelectedItems(KviPointerList * l) -{ - QList list=m_pTreeWidget->selectedItems(); - for(int i=0;iappend((KviAliasEditorTreeWidgetItem *)list.at(i)); - /* if (!((KviAliasEditorTreeWidgetItem *)list.at(i))->isAlias()) - appendSelectedAliasItemsRecursive(l,list.at(i));*/ - } - -} -void KviAliasEditor::appendSelectedItemsRecursive(KviPointerList * l,QTreeWidgetItem * pStartFrom) -{ - for (int i=0;ichildCount();i++) - { - l->append(((KviAliasEditorTreeWidgetItem *)pStartFrom->child(i))); - if (!((KviAliasEditorTreeWidgetItem *)pStartFrom->child(i))->isAlias()) - appendSelectedAliasItemsRecursive(l,pStartFrom->child(i)); - } -} - -void KviAliasEditor::removeItemChildren(KviAliasEditorTreeWidgetItem *it) -{ - while(it->childCount() > 0) - { - KviAliasEditorTreeWidgetItem * pChild = (KviAliasEditorTreeWidgetItem *)(it->child(0)); - if(pChild->childCount()) - removeItemChildren(pChild); - delete pChild; - m_pAliases->removeRef(pChild); - } -} - -bool KviAliasEditor::removeItem(KviAliasEditorTreeWidgetItem *it,bool * pbYesToAll,bool) -{ - if(!it)return true; - QString szMsg; - QString szName = it->name(); - - if(!*pbYesToAll) - { - if(it->isAlias()) - KviQString::sprintf(szMsg,__tr2qs_ctx("Do you really want to remove the alias \"%Q\" ?","editor"),&szName); - else { - KviQString::sprintf(szMsg,__tr2qs_ctx("Do you really want to remove the namespace \"%Q\" ?","editor"),&szName); - szMsg += "
"; - szMsg += __tr2qs_ctx("Please note that all the children items will be deleted too.","editor"); - } - - g_pAliasEditorModule->lock(); - int ret = QMessageBox::question(this,__tr2qs_ctx("Remove item","editor"),szMsg,__tr2qs_ctx("Yes","editor"),__tr2qs_ctx("Yes to All","editor"),__tr2qs_ctx("No","editor")); - g_pAliasEditorModule->unlock(); - switch(ret) - { - case 0: - // nothing - break; - case 1: - *pbYesToAll = true; - break; - default: - return false; - break; - } - } - - if(it == m_pLastEditedItem) - m_pLastEditedItem = 0; - if(it == m_pLastClickedItem) - m_pLastClickedItem = 0; - if (it->childCount()) - removeItemChildren(it); - delete it; - m_pAliases->removeRef(it); - return true; -} - -void KviAliasEditor::removeSelectedItems() -{ - KviPointerList l; - l.setAutoDelete(false); - appendSelectedItems(&l); - bool bYesToAll = false; - for(KviAliasEditorTreeWidgetItem *it = l.first();it;it = l.next()) - { - if(!removeItem(it,&bYesToAll,false))return; - } -} - -QString KviAliasEditor::askForAliasName(const QString &szAction,const QString &szText,const QString &szInitialText) -{ - bool bOk = false; - QString szNewName; - while(szNewName.isEmpty()) - { - g_pAliasEditorModule->lock(); - szNewName = QInputDialog::getText(this, - szAction, - szText, - QLineEdit::Normal, - szInitialText, - &bOk); - g_pAliasEditorModule->unlock(); - if(!bOk)return QString(); - if(szNewName.isEmpty()) - { - g_pAliasEditorModule->lock(); - QMessageBox::warning(this, - __tr2qs_ctx("Missing Alias Name","editor"), - __tr2qs_ctx("You must specify a valid name for the alias","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - g_pAliasEditorModule->unlock(); - continue; - } - - // we allow only [\w:]+ - QRegExp re("[\\w:]+"); - if(!re.exactMatch(szNewName)) - { - g_pAliasEditorModule->lock(); - QMessageBox::information(this, - __tr2qs_ctx("Bad Alias Name","editor"), - __tr2qs_ctx("Alias names can contain only letters, digits, underscores and '::' namespace separators","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - g_pAliasEditorModule->unlock(); - szNewName = ""; - continue; - } - // make sure that we have only doubled "::" and not ":" or ":::..." - QString tmp = szNewName; - tmp.replace("::","@"); // @ is not allowed by the rule above - if(tmp.indexOf(":",Qt::CaseInsensitive) != -1) - { - g_pAliasEditorModule->lock(); - QMessageBox::information(this, - __tr2qs_ctx("Bad Alias Name","editor"), - __tr2qs_ctx("Stray ':' character in alias name: did you mean ...:: ?","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - g_pAliasEditorModule->unlock(); - szNewName = ""; - continue; - } - if(tmp.indexOf("@@",Qt::CaseInsensitive) != -1) - { - g_pAliasEditorModule->lock(); - QMessageBox::information(this, - __tr2qs_ctx("Bad Alias Name","editor"), - __tr2qs_ctx("Found an empty namespace in alias name","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - g_pAliasEditorModule->unlock(); - szNewName = ""; - continue; - } - } - return szNewName; -} - -QString KviAliasEditor::askForNamespaceName(const QString &szAction,const QString &szText,const QString &szInitialText) -{ - bool bOk = false; - QString szNewName; - while(szNewName.isEmpty()) - { - g_pAliasEditorModule->lock(); - szNewName = QInputDialog::getText(this, - szAction, - szText, - QLineEdit::Normal, - szInitialText, - &bOk); - g_pAliasEditorModule->unlock(); - if(!bOk)return QString(); - if(szNewName.isEmpty()) - { - g_pAliasEditorModule->lock(); - QMessageBox::warning(this, - __tr2qs_ctx("Missing Namespace Name","editor"), - __tr2qs_ctx("You must specify a valid name for the namespace","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - g_pAliasEditorModule->unlock(); - continue; - } - - // we allow only [\w:]+ - QRegExp re("[\\w:]+"); - if(!re.exactMatch(szNewName)) - { - g_pAliasEditorModule->lock(); - QMessageBox::information(this, - __tr2qs_ctx("Bad Namespace Name","editor"), - __tr2qs_ctx("Namespace names can contain only letters, digits, underscores and '::' namespace separators","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - g_pAliasEditorModule->unlock(); - szNewName = ""; - continue; - } - // make sure that we have only doubled "::" and not ":" or ":::..." - QString tmp = szNewName; - tmp.replace("::","@"); // @ is not allowed by the rule above - if(tmp.indexOf(":",Qt::CaseInsensitive) != -1) - { - g_pAliasEditorModule->lock(); - QMessageBox::information(this, - __tr2qs_ctx("Bad Namespace Name","editor"), - __tr2qs_ctx("Stray ':' character in namespace name: did you mean ...:: ?","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - g_pAliasEditorModule->unlock(); - szNewName = ""; - continue; - } - if(tmp.indexOf("@@",Qt::CaseInsensitive) != -1) - { - g_pAliasEditorModule->lock(); - QMessageBox::information(this, - __tr2qs_ctx("Bad Namespace Name","editor"), - __tr2qs_ctx("Found an empty namespace in namespace name","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - g_pAliasEditorModule->unlock(); - szNewName = ""; - continue; - } - } - return szNewName; -} - -void KviAliasEditor::openParentItems(QTreeWidgetItem * it) -{ - if(it->parent()) - { - it->parent()->setExpanded(true); - openParentItems(it->parent()); - } -} - -void KviAliasEditor::activateItem(QTreeWidgetItem * it) -{ - if (!it) return; - openParentItems(it); - m_pTreeWidget->setCurrentItem(it); -} -void KviAliasEditor::newAlias() -{ - QString szNewName = askForAliasName(__tr2qs_ctx("Add Alias","editor"),__tr2qs_ctx("Please enter the name for the new alias","editor"),"myfunction"); - if(szNewName.isEmpty())return; - newItem(szNewName,KviAliasEditorTreeWidgetItem::Alias); -} - -void KviAliasEditor::newNamespace() -{ - QString szName = askForNamespaceName(__tr2qs_ctx("Add Namespace","editor"),__tr2qs_ctx("Please enter the name for the new namespace","editor"),"mynamespace"); - if(szName.isEmpty())return; - newItem(szName,KviAliasEditorTreeWidgetItem::Namespace); -} - -void KviAliasEditor::newItem(QString &szName,KviAliasEditorTreeWidgetItem::Type eType) -{ - if(m_pLastClickedItem) - if(!itemExists(m_pLastClickedItem)) m_pLastClickedItem=0; - if(m_pLastClickedItem) buildFullItemPath(m_pLastClickedItem,szName); - int idx=1; - QString szTmp; - if(findItem(szName)) szName.append("1"); - while(findItem(szName)) - { - szTmp.setNum(idx); - szName.chop(szTmp.length()); - szName.append(szTmp); - idx++; - } - KviAliasEditorTreeWidgetItem * it; - it=createFullItem(szName); - it->setType(eType); - m_pAliases->append(it); - activateItem(it); -} - -void KviAliasEditor::commit() -{ - m_bSaving = true; - saveLastEditedItem(); - KviKvsAliasManager::instance()->clear(); - for(unsigned int i=0;icount();i++) - { - QString szName = buildFullItemName(m_pAliases->at(i)); - KviKvsScript * a = new KviKvsScript(szName,m_pAliases->at(i)->buffer()); - KviKvsAliasManager::instance()->add(szName,a); - } - g_pApp->saveAliases(); - m_bSaving = false; -} - - -KviAliasEditorWindow::KviAliasEditorWindow(KviMainWindow * lpFrm) -: KviWindow(KVI_WINDOW_TYPE_SCRIPTEDITOR,lpFrm,"aliaseditor",0) -{ - g_pAliasEditorWindow = this; - - setFixedCaption(__tr2qs_ctx("Alias Editor","editor")); - - QGridLayout * g = new QGridLayout(); - - m_pEditor = new KviAliasEditor(this); - g->addWidget(m_pEditor,0,0,1,4); - - QPushButton * btn = new QPushButton(__tr2qs_ctx("&OK","editor"),this); - connect(btn,SIGNAL(clicked()),this,SLOT(okClicked())); - btn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT))); - g->addWidget(btn,1,1); - - btn = new QPushButton(__tr2qs_ctx("&Apply","editor"),this); - connect(btn,SIGNAL(clicked()),this,SLOT(applyClicked())); - btn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT))); - g->addWidget(btn,1,2); - - btn = new QPushButton(__tr2qs_ctx("Cancel","editor"),this); - connect(btn,SIGNAL(clicked()),this,SLOT(cancelClicked())); - btn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD))); - g->addWidget(btn,1,3); - - g->setRowStretch(0,1); - g->setColumnStretch(0,1); - setLayout(g); -} - -KviAliasEditorWindow::~KviAliasEditorWindow() -{ - g_pAliasEditorWindow = 0; -} - -void KviAliasEditorWindow::okClicked() -{ - m_pEditor->commit(); - close(); -} - -void KviAliasEditorWindow::applyClicked() -{ - m_pEditor->commit(); -} - -void KviAliasEditorWindow::cancelClicked() -{ - close(); -} - -QPixmap * KviAliasEditorWindow::myIconPtr() -{ - return g_pIconManager->getSmallIcon(KVI_SMALLICON_ALIAS); -} - -void KviAliasEditorWindow::getConfigGroupName(QString &szName) -{ - szName = "aliaseditor"; -} - -void KviAliasEditorWindow::saveProperties(KviConfigurationFile *cfg) -{ - m_pEditor->saveProperties(cfg); -} - -void KviAliasEditorWindow::loadProperties(KviConfigurationFile *cfg) -{ - m_pEditor->loadProperties(cfg); -} diff --git a/src/modules/aliaseditor/aliaseditor.h b/src/modules/aliaseditor/aliaseditor.h deleted file mode 100644 index 34fefcb47..000000000 --- a/src/modules/aliaseditor/aliaseditor.h +++ /dev/null @@ -1,190 +0,0 @@ -#ifndef _ALIASEDITOR_H_ -#define _ALIASEDITOR_H_ -//============================================================================= -// -// File : aliaseditor.h -// Creation date : Mon Dec 23 2002 14:35:55 CEST by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the linkss of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "KviWindow.h" -#include "KviCString.h" -#include "KviPointerList.h" -#include "KviTalPopupMenu.h" -#include "KviHeapObject.h" - -#include -#include -#include -#include -#include -#include - - -class QSplitter; -class KviScriptEditor; - - - -class KviAliasEditorTreeWidgetItem : public QTreeWidgetItem, public KviHeapObject -{ -public: - enum Type { Alias, Namespace }; -public: - KviAliasEditorTreeWidgetItem(QTreeWidget * pTreeWidget,Type eType,const QString &szName); - KviAliasEditorTreeWidgetItem(KviAliasEditorTreeWidgetItem * pParentItem,Type eType,const QString &szName); - ~KviAliasEditorTreeWidgetItem(){}; -protected: - Type m_eType; - KviAliasEditorTreeWidgetItem * m_pParentItem; - QString m_szName; - QString m_szBuffer; - int m_cPos; -public: - inline const QString & name(){ return m_szName; }; - void setName(const QString &szName); - inline Type type(){ return m_eType; }; - void setType(Type t); - inline bool isAlias(){ return m_eType == Alias; }; - inline bool isNamespace(){ return m_eType == Namespace; }; - void setParentItem(KviAliasEditorTreeWidgetItem* it){ m_pParentItem=it; }; - KviAliasEditorTreeWidgetItem * parentItem(){ return m_pParentItem; }; - inline void setBuffer(const QString &szBuffer){ m_szBuffer = szBuffer; }; - inline const QString & buffer(){ return m_szBuffer; }; - inline const int & cursorPosition(){return m_cPos; }; - - void setCursorPosition(const int &cPos){ m_cPos = cPos; }; -}; - - - -class KviAliasEditorTreeWidget : public QTreeWidget -{ - Q_OBJECT -public: - KviAliasEditorTreeWidget(QWidget*); - ~KviAliasEditorTreeWidget(); -}; - -class KviAliasEditor : public QWidget -{ - Q_OBJECT -public: - KviAliasEditor(QWidget * par); - ~KviAliasEditor(); -public: - KviScriptEditor * m_pEditor; - KviAliasEditorTreeWidget * m_pTreeWidget; - QLabel * m_pNameLabel; - QPushButton * m_pRenameButton; - KviAliasEditorTreeWidgetItem * m_pLastEditedItem; - KviAliasEditorTreeWidgetItem * m_pLastClickedItem; - KviTalPopupMenu * m_pContextPopup; - QSplitter * m_pSplitter; - QString m_szDir; - bool m_bSaving; -public: - //bool modified(){ return m_bModified; }; - void commit(); - void exportAliases(bool,bool=false); - void exportSelectionInSinglesFiles(KviPointerList *l); - - void saveProperties(KviConfigurationFile *); - void loadProperties(KviConfigurationFile *); - static void splitFullAliasOrNamespaceName(const QString &szFullName,QStringList &lNamespaces,QString &szName); -protected slots: - void currentItemChanged(QTreeWidgetItem *it,QTreeWidgetItem *); - void renameItem(); - void newAlias(); - void customContextMenuRequested(const QPoint pnt); - void newNamespace(); - void newItem(QString &szName,KviAliasEditorTreeWidgetItem::Type eType); - - void exportAll(); - void exportSelectedSepFiles(); - void exportSelected(); - - void removeSelectedItems(); - void slotFind(); - void slotCollapseNamespaces(); - void slotFindWord(const QString &); - void slotReplaceAll(const QString &before,const QString &after); - void itemRenamed(QTreeWidgetItem *it,int col); - void aliasRefresh(const QString &szName); - -protected: - KviPointerList *m_pAliases; - void recursiveCollapseNamespaces(KviAliasEditorTreeWidgetItem * it); - void searchReplace(const QString &szSearch,bool bReplace=false,const QString &szReplace="n"); - - void getExportAliasBuffer(QString &buffer,KviAliasEditorTreeWidgetItem * it); - void oneTimeSetup(); - void saveLastEditedItem(); - void getUniqueItemName(KviAliasEditorTreeWidgetItem *item,QString &buffer,KviAliasEditorTreeWidgetItem::Type eType); - void appendSelectedAliasItems(KviPointerList * l); - void appendSelectedAliasItemsRecursive(KviPointerList * l,QTreeWidgetItem * pStartFrom); - void appendSelectedItems(KviPointerList * l); - void appendSelectedItemsRecursive(KviPointerList * l,QTreeWidgetItem * pStartFrom); - - void openParentItems(QTreeWidgetItem * it); - void activateItem(QTreeWidgetItem * it); - - bool removeItem(KviAliasEditorTreeWidgetItem *it,bool * pbYesToAll,bool bDeleteEmptyTree); - void removeItemChildren(KviAliasEditorTreeWidgetItem *it); - - QString askForAliasName(const QString &szAction,const QString &szText,const QString &szInitialText); - QString askForNamespaceName(const QString &szAction,const QString &szText,const QString &szInitialText); -// - bool itemExists(QTreeWidgetItem *pSearchFor); - bool namespaceExists(QString &szFullItemName); - bool aliasExists(QString &szFullItemName); - void appendAllItems(KviPointerList * l,KviAliasEditorTreeWidgetItem::Type); - void appendAllItemsRecursive(KviPointerList * l,QTreeWidgetItem * pStartFrom,KviAliasEditorTreeWidgetItem::Type); - bool hasSelectedItems(); - void buildAliasesFile(KviPointerList *l, QString & szBuffer); - - void buildFullItemPath(KviAliasEditorTreeWidgetItem * it,QString &szBuffer); - KviAliasEditorTreeWidgetItem * findTopLevelItem(const QString &szName); - KviAliasEditorTreeWidgetItem * createFullItem(const QString &szFullName); - KviAliasEditorTreeWidgetItem * findItem(const QString &szName); - QString buildFullItemName(KviAliasEditorTreeWidgetItem * it); -}; - - -class KviAliasEditorWindow : public KviWindow -{ - Q_OBJECT -public: - KviAliasEditorWindow(KviMainWindow * lpFrm); - ~KviAliasEditorWindow(); -protected: - KviAliasEditor * m_pEditor; -protected: - virtual QPixmap * myIconPtr(); - virtual void getConfigGroupName(QString &szName); - virtual void saveProperties(KviConfigurationFile *); - virtual void loadProperties(KviConfigurationFile *); -protected slots: - void cancelClicked(); - void okClicked(); - void applyClicked(); -}; - -#endif //_ALIASEDITOR_H_ diff --git a/src/modules/aliaseditor/libkvialiaseditor.cpp b/src/modules/aliaseditor/libkvialiaseditor.cpp index 00f09ca5e..ffa63d704 100644 --- a/src/modules/aliaseditor/libkvialiaseditor.cpp +++ b/src/modules/aliaseditor/libkvialiaseditor.cpp @@ -22,14 +22,14 @@ // //============================================================================= -#include "aliaseditor.h" +#include "AliasEditorWindow.h" #include "KviModule.h" #include "KviLocale.h" #include "KviMainWindow.h" -KviAliasEditorWindow * g_pAliasEditorWindow = 0; +AliasEditorWindow * g_pAliasEditorWindow = 0; KviModule * g_pAliasEditorModule = 0; @@ -51,7 +51,7 @@ static bool aliaseditor_kvs_cmd_open(KviKvsModuleCommandCall * c) { if(!g_pAliasEditorWindow) { - g_pAliasEditorWindow = new KviAliasEditorWindow(c->window()->frame()); + g_pAliasEditorWindow = new AliasEditorWindow(c->window()->frame()); c->window()->frame()->addWindow(g_pAliasEditorWindow); } diff --git a/src/modules/channelsjoin/CMakeLists.txt b/src/modules/channelsjoin/CMakeLists.txt index 06805bacb..1abae2f9e 100644 --- a/src/modules/channelsjoin/CMakeLists.txt +++ b/src/modules/channelsjoin/CMakeLists.txt @@ -2,10 +2,10 @@ SET(kvichannelsjoin_SRCS libkvichannelsjoin.cpp - channelsjoinwindow.cpp + ChannelsJoinDialog.cpp ) SET(kvichannelsjoin_MOC_HDRS - channelsjoinwindow.h + ChannelsJoinDialog.h ) # After this call, files will be moc'ed to moc_kvi_*.cpp QT4_WRAP_CPP(kvichannelsjoin_MOC_SRCS ${kvichannelsjoin_MOC_HDRS}) diff --git a/src/modules/channelsjoin/ChannelsJoinDialog.cpp b/src/modules/channelsjoin/ChannelsJoinDialog.cpp new file mode 100644 index 000000000..65e307028 --- /dev/null +++ b/src/modules/channelsjoin/ChannelsJoinDialog.cpp @@ -0,0 +1,413 @@ +//============================================================================= +// +// File : ChannelsJoinDialog.cpp +// Creation date : Thu Nov 6 2001 12:41:18 by Juanjo �varez +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the linkss of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "ChannelsJoinDialog.h" + +#include "KviLocale.h" +#include "KviOptions.h" +#include "KviSelectors.h" +#include "KviApplication.h" +#include "KviCString.h" +#include "KviQString.h" +#include "KviIconManager.h" +#include "KviConsoleWindow.h" +#include "KviRegisteredChannel.h" +#include "KviRegisteredChannelDataBase.h" +#include "KviKvsScript.h" +#include "KviTalGroupBox.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +extern ChannelsJoinDialog * g_pChannelsWindow; +extern QRect g_rectChannelsJoinGeometry; +// KviApplication.cpp +extern KVIRC_API KviRegisteredChannelDataBase * g_pRegisteredChannelDataBase; + + +ChannelsJoinDialog::ChannelsJoinDialog(QWidget * par, const char * name) +: QDialog(par) +{ + setObjectName(name); + setWindowTitle(__tr2qs("Join Channels")); + setWindowIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL))); + + m_pConsole = 0; + + QGridLayout * g = new QGridLayout(this); + + m_pTreeWidget = new QTreeWidget(this); + m_pTreeWidget->setHeaderLabel(__tr2qs("Channel")); + m_pTreeWidget->setRootIsDecorated(true); + m_pTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); + g->addWidget(m_pTreeWidget,0,0,1,2); + connect(m_pTreeWidget,SIGNAL(itemClicked(QTreeWidgetItem *,int)),this,SLOT(itemClicked(QTreeWidgetItem *,int))); + connect(m_pTreeWidget,SIGNAL(itemDoubleClicked(QTreeWidgetItem *,int)),this,SLOT(itemDoubleClicked(QTreeWidgetItem *,int))); + + + m_pGroupBox = new KviTalGroupBox(Qt::Horizontal,__tr2qs("Channel" ),this); + QString szMsg = __tr2qs("Name"); + szMsg.append(":"); + + new QLabel(szMsg,m_pGroupBox); + + m_pChannelEdit = new QLineEdit(m_pGroupBox); + connect(m_pChannelEdit,SIGNAL(returnPressed()), this, SLOT(editReturnPressed())); + connect(m_pChannelEdit,SIGNAL(textChanged(const QString &)),this,SLOT(editTextChanged(const QString &))); + + szMsg = __tr2qs("Password"); + szMsg.append(":"); + QLabel(szMsg,m_pGroupBox); + + m_pPass = new QLineEdit(m_pGroupBox); + m_pPass->setEchoMode(QLineEdit::Password); + + g->addWidget(m_pGroupBox,1,0,1,2); + + KviTalHBox * hb = new KviTalHBox(this); + hb->setSpacing(4); + + g->addWidget(hb,2,0,1,2,Qt::AlignHCenter); + + m_pJoinButton = new QPushButton(__tr2qs("&Join"),hb); + // Join on return pressed + m_pJoinButton->setDefault(true); + connect(m_pJoinButton,SIGNAL(clicked()),this,SLOT(joinClicked())); + + m_pRegButton = new QPushButton(__tr2qs("&Register"),hb); + // Join on return pressed + connect(m_pRegButton,SIGNAL(clicked()),this,SLOT(regClicked())); + + m_pClearButton = new QPushButton(__tr2qs("Clear Recent"),hb); + connect(m_pClearButton,SIGNAL(clicked()),this,SLOT(clearClicked())); + + m_pShowAtStartupCheck = new QCheckBox(__tr2qs("Show this window after connecting"),this); + m_pShowAtStartupCheck->setChecked(KVI_OPTION_BOOL(KviOption_boolShowChannelsJoinOnIrc)); + g->addWidget(m_pShowAtStartupCheck,3,0); + + + QPushButton * cancelButton = new QPushButton(__tr2qs("Close"),this); + connect(cancelButton,SIGNAL(clicked()),this,SLOT(cancelClicked())); + + g->addWidget(cancelButton,3,1); + +/* + KviTalHBox * hb = new KviTalHBox(this); + hb->setSpacing(4); + + QPushButton * namesButton = new QPushButton("/names", hb); + connect(namesButton,SIGNAL(clicked()),this,SLOT(namesClicked())); + QPushButton * whoButton = new QPushButton("/who", hb); + connect(whoButton,SIGNAL(clicked()),this,SLOT(whoClicked())); + + g->addWidget(hb,2,0); +*/ + + g->setRowStretch(0,1); + g->setColumnStretch(0,1); + + fillListView(); + + if(g_rectChannelsJoinGeometry.y() < 5)g_rectChannelsJoinGeometry.setY(5); + + resize(g_rectChannelsJoinGeometry.width(),g_rectChannelsJoinGeometry.height()); + move(g_rectChannelsJoinGeometry.x(),g_rectChannelsJoinGeometry.y()); + + enableJoin(); +} + +ChannelsJoinDialog::~ChannelsJoinDialog() +{ + KVI_OPTION_BOOL(KviOption_boolShowChannelsJoinOnIrc) = m_pShowAtStartupCheck->isChecked(); + + g_rectChannelsJoinGeometry = QRect(pos().x(),pos().y(),size().width(),size().height()); + g_pChannelsWindow = 0; +} + +void ChannelsJoinDialog::setConsole(KviConsoleWindow * pConsole) +{ + m_pConsole = pConsole; + fillListView(); +} + +void ChannelsJoinDialog::fillListView() +{ + m_pTreeWidget->clear(); + + m_pTreeWidget->header()->hide(); + + // Registered channels go first + + QTreeWidgetItem * par = new QTreeWidgetItem(m_pTreeWidget); + par->setText(0,__tr2qs("Registered Channels")); + par->setExpanded(true); + + QHash * d = g_pRegisteredChannelDataBase->channelDict(); + if(d) + { + for(QHash::Iterator it = d->begin();it != d->end();++it) + { + QTreeWidgetItem * chld = new QTreeWidgetItem(par); + chld->setText(0,it.key()); + chld->setIcon(0,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL))); + } + } + + par = new QTreeWidgetItem(m_pTreeWidget); + par->setText(0,__tr2qs("Recent Channels")); + par->setExpanded(true); + + QTreeWidgetItem * chld; + + bool bGotChanOnCurrentNetwork = false; + + if(m_pConsole) + { + QStringList * pList = g_pApp->recentChannelsForNetwork(m_pConsole->currentNetworkName()); + if(pList) + { + if(pList->count() > 0) + { + bGotChanOnCurrentNetwork = true; + + par = new QTreeWidgetItem(par); + par->setText(0,__tr2qs("Current Network")); + par->setExpanded(true); + + for(QStringList::Iterator it = pList->begin(); it != pList->end(); ++it) + { + chld = new QTreeWidgetItem(par); + chld->setText(0,*it); + chld->setIcon(0,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL))); + } + } + } + } + + KviPointerHashTable * pDict = g_pApp->recentChannels(); + if(!pDict) + return; + + par = new QTreeWidgetItem(par); + par->setText(0,__tr2qs("All Networks")); + + if(!bGotChanOnCurrentNetwork) + par->setExpanded(true); // expand this one instead + + QHash hNoDuplicates; + + for(QStringList * pChans = pDict->first();pChans;pChans = pDict->next()) + { + for(QStringList::Iterator it = pChans->begin(); it != pChans->end(); ++it) + { + QString chan = *it; + if(hNoDuplicates.contains(chan.toLower())) + continue; + hNoDuplicates.insert(chan.toLower(),1); + chld = new QTreeWidgetItem(par); + chld->setText(0,chan); + chld->setIcon(0,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL))); + } + } +} + +void ChannelsJoinDialog::itemClicked(QTreeWidgetItem * it, int) +{ + if(!it) + return; + if(it->childCount()) + return; + + QString szTmp = it->text(0); + m_pChannelEdit->setText(szTmp); + enableJoin(); +} + +void ChannelsJoinDialog::itemDoubleClicked(QTreeWidgetItem * it, int) +{ + if(!it) + return; + if(it->childCount()) + return; + + QString szTmp = it->text(0); + m_pChannelEdit->setText(szTmp); + enableJoin(); + joinClicked(); +} + +void ChannelsJoinDialog::editTextChanged(const QString &) +{ + enableJoin(); +} + +void ChannelsJoinDialog::enableJoin() +{ + QString szTmp = m_pChannelEdit->text(); + KviConsoleWindow * c = g_pApp->topmostConnectedConsole(); + if(c) + { + if(szTmp.isEmpty()) + { + m_pJoinButton->setEnabled(false); + m_pRegButton->setEnabled(false); + } else { + m_pJoinButton->setEnabled(true); + m_pRegButton->setEnabled(true); + } + } else { + m_pTreeWidget->setEnabled(false); + m_pGroupBox->setEnabled(false); + m_pJoinButton->setEnabled(false); + } +} + +void ChannelsJoinDialog::cancelClicked() +{ + delete this; +} + +void ChannelsJoinDialog::joinClicked() +{ + QString szPass = m_pPass->text(); + QString szTmp = m_pChannelEdit->text(); + + if(szTmp.isEmpty()) + return; + + KviQString::escapeKvs(&szTmp); + KviQString::escapeKvs(&szPass); + + QString szCmd = "join "; + szCmd += szTmp; + szCmd += " "; + szCmd += szPass; + + KviConsoleWindow * c = g_pApp->topmostConnectedConsole(); + if(!c) + return; // no connection + + KviWindow * w = g_pActiveWindow; + if(w->console() != c) + w = c; + + KviKvsScript::run(szCmd,w); + + m_pChannelEdit->setText(""); + m_pPass->setText(""); +} + +void ChannelsJoinDialog::regClicked() +{ + QString szTmp = m_pChannelEdit->text(); + + if(szTmp.isEmpty()) + return; + + KviQString::escapeKvs(&szTmp); + QString szCmd = "regchan.add "; + szCmd += szTmp; + + KviConsoleWindow * c = g_pApp->topmostConnectedConsole(); + if(!c) + return; // no connection + + KviWindow * w = g_pActiveWindow; + if(w->console() != c) + w = c; + + KviKvsScript::run(szCmd,w); + fillListView(); + + //focus the new item (in reality, the first matching one) + QList items = m_pTreeWidget->findItems(szTmp, Qt::MatchRecursive | Qt::MatchExactly); + if(!items.empty()) + { + m_pTreeWidget->setCurrentItem(items.first()); + m_pTreeWidget->scrollToItem(items.first()); + } +} + +void ChannelsJoinDialog::clearClicked() +{ + QString szCmd = "option stringlistRecentChannels"; + + KviConsoleWindow * c = g_pApp->topmostConnectedConsole(); + if(!c) + return; // no connection + + KviWindow * w = g_pActiveWindow; + if(w->console() != c) + w = c; + + KviKvsScript::run(szCmd,w); + fillListView(); +} + +/* +void ChannelsJoinDialog::whoClicked() +{ + KviCString tmp = m_pChannelEdit->text(); + if(!tmp.isEmpty())doCmd("who", tmp.ptr()); +} + +void ChannelsJoinDialog::namesClicked() +{ + KviCString tmp = m_pChannelEdit->text(); + //FIXME: I must be a nice guy and implement /names in the core... + if(!tmp.isEmpty())doCmd("raw names", tmp.ptr()); +} + +void ChannelsJoinDialog::itemDoubleClicked(KviTalListBoxItem * it) +{ + if (it == 0)return; + KviCString tmp = it->text(); + doCmd("join", tmp.ptr()); +// if(KVI_OPTION_BOOL(KviOption_boolCloseChannelsJoinAfterJoin)) +// g_pApp->collectGarbage(this); +} +*/ + +void ChannelsJoinDialog::editReturnPressed() +{ + joinClicked(); +} + +void ChannelsJoinDialog::closeEvent(QCloseEvent * e) +{ + e->ignore(); + delete this; +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_ChannelsJoinDialog.moc" +#endif //COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/channelsjoin/ChannelsJoinDialog.h b/src/modules/channelsjoin/ChannelsJoinDialog.h new file mode 100644 index 000000000..b4b64145e --- /dev/null +++ b/src/modules/channelsjoin/ChannelsJoinDialog.h @@ -0,0 +1,162 @@ +#ifndef _CHANNELSJOIN_H_ +#define _CHANNELSJOIN_H_ +//============================================================================= +// +// File : ChannelsJoinDialog.h +// Creation date : Thu Nov 06 2001 12:30:25 CEST by Juan Alvarez +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +/** +* \file ChannelsJoinDialog.h +* \author Juan Alvarez +* \brief Channels join window +*/ + +#include "KviWindow.h" +#include "KviCString.h" +#include + +#include + +class QCheckBox; +class QPushButton; +class QLineEdit; +class KviConsoleWindow; +class KviTalGroupBox; + +/** +* \class ChannelsJoinDialog +* \brief Channels join window class +*/ +class ChannelsJoinDialog : public QDialog +{ + Q_OBJECT +public: + /** + * \brief Constructs the channels join window + * \param par The parent widget + * \param name The name of the window + * \return ChannelsJoinDialog + */ + ChannelsJoinDialog(QWidget * par, const char * name); + + /** + * \brief Destroys the channels join window + */ + ~ChannelsJoinDialog(); +protected: + QLineEdit * m_pChannelEdit; + QTreeWidget * m_pTreeWidget; + KviTalGroupBox * m_pGroupBox; + QLineEdit * m_pPass; + QCheckBox * m_pShowAtStartupCheck; + QCheckBox * m_pCloseAfterJoinCheck; + QPushButton * m_pJoinButton; + QPushButton * m_pRegButton; + QPushButton * m_pClearButton; + KviConsoleWindow * m_pConsole; +public: + virtual void closeEvent(QCloseEvent * e); + + /** + * \brief Fills in the servers' list + * \return void + */ + void fillListView(); + + /** + * \brief Enables join and register button if channel is found + * \return void + */ + void enableJoin(); + + /** + * \brief Sets the console and fills in the servers' list + * \param pConsole The source console + * \return void + */ + void setConsole(KviConsoleWindow * pConsole); +protected slots: + /** + * \brief Called when the text changes + * \return void + */ + void editTextChanged(const QString &); + + /** + * \brief Called when an item is clicked + * \param it The item clicked + * \return void + */ + void itemClicked(QTreeWidgetItem * it, int); + + /** + * \brief Called when an item is double-clicked + * \param it The item clicked + * \return void + */ + void itemDoubleClicked(QTreeWidgetItem * it, int); + + /** + * \brief Called when the return is pressed + * + * It joins the selected channel + * \return void + */ + void editReturnPressed(); + + /** + * \brief Called when the cancel button is pressed + * + * It destroys the window object + * \return void + */ + void cancelClicked(); + + /** + * \brief Called when the join button is pressed + * + * It joins the selected channel + * \return void + */ + void joinClicked(); + + /** + * \brief Called when the register button is pressed + * + * It registers the selected channel in the database + * \return void + */ + void regClicked(); + + /** + * \brief Called when the clear button is pressed + * + * It clears the list of recent channels + * \return void + */ + void clearClicked(); + + //void whoClicked(); + //void namesClicked(); +}; + +#endif //_CHANNELSJOINSWINDOW_H_ diff --git a/src/modules/channelsjoin/channelsjoinwindow.cpp b/src/modules/channelsjoin/channelsjoinwindow.cpp deleted file mode 100644 index 2372e885c..000000000 --- a/src/modules/channelsjoin/channelsjoinwindow.cpp +++ /dev/null @@ -1,413 +0,0 @@ -//============================================================================= -// -// File : channelsjoinwindow.cpp -// Creation date : Thu Nov 6 2001 12:41:18 by Juanjo �varez -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the linkss of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "channelsjoinwindow.h" - -#include "KviLocale.h" -#include "KviOptions.h" -#include "KviSelectors.h" -#include "KviApplication.h" -#include "KviCString.h" -#include "KviQString.h" -#include "KviIconManager.h" -#include "KviConsoleWindow.h" -#include "KviRegisteredChannel.h" -#include "KviRegisteredChannelDataBase.h" -#include "KviKvsScript.h" -#include "KviTalGroupBox.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -extern KviChannelsJoinWindow * g_pChannelsWindow; -extern QRect g_rectChannelsJoinGeometry; -// KviApplication.cpp -extern KVIRC_API KviRegisteredChannelDataBase * g_pRegisteredChannelDataBase; - - -KviChannelsJoinWindow::KviChannelsJoinWindow(QWidget * par, const char * name) -: QDialog(par) -{ - setObjectName(name); - setWindowTitle(__tr2qs("Join Channels")); - setWindowIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL))); - - m_pConsole = 0; - - QGridLayout * g = new QGridLayout(this); - - m_pTreeWidget = new QTreeWidget(this); - m_pTreeWidget->setHeaderLabel(__tr2qs("Channel")); - m_pTreeWidget->setRootIsDecorated(true); - m_pTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); - g->addWidget(m_pTreeWidget,0,0,1,2); - connect(m_pTreeWidget,SIGNAL(itemClicked(QTreeWidgetItem *,int)),this,SLOT(itemClicked(QTreeWidgetItem *,int))); - connect(m_pTreeWidget,SIGNAL(itemDoubleClicked(QTreeWidgetItem *,int)),this,SLOT(itemDoubleClicked(QTreeWidgetItem *,int))); - - - m_pGroupBox = new KviTalGroupBox(Qt::Horizontal,__tr2qs("Channel" ),this); - QString szMsg = __tr2qs("Name"); - szMsg.append(":"); - - new QLabel(szMsg,m_pGroupBox); - - m_pChannelEdit = new QLineEdit(m_pGroupBox); - connect(m_pChannelEdit,SIGNAL(returnPressed()), this, SLOT(editReturnPressed())); - connect(m_pChannelEdit,SIGNAL(textChanged(const QString &)),this,SLOT(editTextChanged(const QString &))); - - szMsg = __tr2qs("Password"); - szMsg.append(":"); - QLabel(szMsg,m_pGroupBox); - - m_pPass = new QLineEdit(m_pGroupBox); - m_pPass->setEchoMode(QLineEdit::Password); - - g->addWidget(m_pGroupBox,1,0,1,2); - - KviTalHBox * hb = new KviTalHBox(this); - hb->setSpacing(4); - - g->addWidget(hb,2,0,1,2,Qt::AlignHCenter); - - m_pJoinButton = new QPushButton(__tr2qs("&Join"),hb); - // Join on return pressed - m_pJoinButton->setDefault(true); - connect(m_pJoinButton,SIGNAL(clicked()),this,SLOT(joinClicked())); - - m_pRegButton = new QPushButton(__tr2qs("&Register"),hb); - // Join on return pressed - connect(m_pRegButton,SIGNAL(clicked()),this,SLOT(regClicked())); - - m_pClearButton = new QPushButton(__tr2qs("Clear Recent"),hb); - connect(m_pClearButton,SIGNAL(clicked()),this,SLOT(clearClicked())); - - m_pShowAtStartupCheck = new QCheckBox(__tr2qs("Show this window after connecting"),this); - m_pShowAtStartupCheck->setChecked(KVI_OPTION_BOOL(KviOption_boolShowChannelsJoinOnIrc)); - g->addWidget(m_pShowAtStartupCheck,3,0); - - - QPushButton * cancelButton = new QPushButton(__tr2qs("Close"),this); - connect(cancelButton,SIGNAL(clicked()),this,SLOT(cancelClicked())); - - g->addWidget(cancelButton,3,1); - -/* - KviTalHBox * hb = new KviTalHBox(this); - hb->setSpacing(4); - - QPushButton * namesButton = new QPushButton("/names", hb); - connect(namesButton,SIGNAL(clicked()),this,SLOT(namesClicked())); - QPushButton * whoButton = new QPushButton("/who", hb); - connect(whoButton,SIGNAL(clicked()),this,SLOT(whoClicked())); - - g->addWidget(hb,2,0); -*/ - - g->setRowStretch(0,1); - g->setColumnStretch(0,1); - - fillListView(); - - if(g_rectChannelsJoinGeometry.y() < 5)g_rectChannelsJoinGeometry.setY(5); - - resize(g_rectChannelsJoinGeometry.width(),g_rectChannelsJoinGeometry.height()); - move(g_rectChannelsJoinGeometry.x(),g_rectChannelsJoinGeometry.y()); - - enableJoin(); -} - -KviChannelsJoinWindow::~KviChannelsJoinWindow() -{ - KVI_OPTION_BOOL(KviOption_boolShowChannelsJoinOnIrc) = m_pShowAtStartupCheck->isChecked(); - - g_rectChannelsJoinGeometry = QRect(pos().x(),pos().y(),size().width(),size().height()); - g_pChannelsWindow = 0; -} - -void KviChannelsJoinWindow::setConsole(KviConsoleWindow * pConsole) -{ - m_pConsole = pConsole; - fillListView(); -} - -void KviChannelsJoinWindow::fillListView() -{ - m_pTreeWidget->clear(); - - m_pTreeWidget->header()->hide(); - - // Registered channels go first - - QTreeWidgetItem * par = new QTreeWidgetItem(m_pTreeWidget); - par->setText(0,__tr2qs("Registered Channels")); - par->setExpanded(true); - - QHash * d = g_pRegisteredChannelDataBase->channelDict(); - if(d) - { - for(QHash::Iterator it = d->begin();it != d->end();++it) - { - QTreeWidgetItem * chld = new QTreeWidgetItem(par); - chld->setText(0,it.key()); - chld->setIcon(0,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL))); - } - } - - par = new QTreeWidgetItem(m_pTreeWidget); - par->setText(0,__tr2qs("Recent Channels")); - par->setExpanded(true); - - QTreeWidgetItem * chld; - - bool bGotChanOnCurrentNetwork = false; - - if(m_pConsole) - { - QStringList * pList = g_pApp->recentChannelsForNetwork(m_pConsole->currentNetworkName()); - if(pList) - { - if(pList->count() > 0) - { - bGotChanOnCurrentNetwork = true; - - par = new QTreeWidgetItem(par); - par->setText(0,__tr2qs("Current Network")); - par->setExpanded(true); - - for(QStringList::Iterator it = pList->begin(); it != pList->end(); ++it) - { - chld = new QTreeWidgetItem(par); - chld->setText(0,*it); - chld->setIcon(0,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL))); - } - } - } - } - - KviPointerHashTable * pDict = g_pApp->recentChannels(); - if(!pDict) - return; - - par = new QTreeWidgetItem(par); - par->setText(0,__tr2qs("All Networks")); - - if(!bGotChanOnCurrentNetwork) - par->setExpanded(true); // expand this one instead - - QHash hNoDuplicates; - - for(QStringList * pChans = pDict->first();pChans;pChans = pDict->next()) - { - for(QStringList::Iterator it = pChans->begin(); it != pChans->end(); ++it) - { - QString chan = *it; - if(hNoDuplicates.contains(chan.toLower())) - continue; - hNoDuplicates.insert(chan.toLower(),1); - chld = new QTreeWidgetItem(par); - chld->setText(0,chan); - chld->setIcon(0,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL))); - } - } -} - -void KviChannelsJoinWindow::itemClicked(QTreeWidgetItem * it, int) -{ - if(!it) - return; - if(it->childCount()) - return; - - QString szTmp = it->text(0); - m_pChannelEdit->setText(szTmp); - enableJoin(); -} - -void KviChannelsJoinWindow::itemDoubleClicked(QTreeWidgetItem * it, int) -{ - if(!it) - return; - if(it->childCount()) - return; - - QString szTmp = it->text(0); - m_pChannelEdit->setText(szTmp); - enableJoin(); - joinClicked(); -} - -void KviChannelsJoinWindow::editTextChanged(const QString &) -{ - enableJoin(); -} - -void KviChannelsJoinWindow::enableJoin() -{ - QString szTmp = m_pChannelEdit->text(); - KviConsoleWindow * c = g_pApp->topmostConnectedConsole(); - if(c) - { - if(szTmp.isEmpty()) - { - m_pJoinButton->setEnabled(false); - m_pRegButton->setEnabled(false); - } else { - m_pJoinButton->setEnabled(true); - m_pRegButton->setEnabled(true); - } - } else { - m_pTreeWidget->setEnabled(false); - m_pGroupBox->setEnabled(false); - m_pJoinButton->setEnabled(false); - } -} - -void KviChannelsJoinWindow::cancelClicked() -{ - delete this; -} - -void KviChannelsJoinWindow::joinClicked() -{ - QString szPass = m_pPass->text(); - QString szTmp = m_pChannelEdit->text(); - - if(szTmp.isEmpty()) - return; - - KviQString::escapeKvs(&szTmp); - KviQString::escapeKvs(&szPass); - - QString szCmd = "join "; - szCmd += szTmp; - szCmd += " "; - szCmd += szPass; - - KviConsoleWindow * c = g_pApp->topmostConnectedConsole(); - if(!c) - return; // no connection - - KviWindow * w = g_pActiveWindow; - if(w->console() != c) - w = c; - - KviKvsScript::run(szCmd,w); - - m_pChannelEdit->setText(""); - m_pPass->setText(""); -} - -void KviChannelsJoinWindow::regClicked() -{ - QString szTmp = m_pChannelEdit->text(); - - if(szTmp.isEmpty()) - return; - - KviQString::escapeKvs(&szTmp); - QString szCmd = "regchan.add "; - szCmd += szTmp; - - KviConsoleWindow * c = g_pApp->topmostConnectedConsole(); - if(!c) - return; // no connection - - KviWindow * w = g_pActiveWindow; - if(w->console() != c) - w = c; - - KviKvsScript::run(szCmd,w); - fillListView(); - - //focus the new item (in reality, the first matching one) - QList items = m_pTreeWidget->findItems(szTmp, Qt::MatchRecursive | Qt::MatchExactly); - if(!items.empty()) - { - m_pTreeWidget->setCurrentItem(items.first()); - m_pTreeWidget->scrollToItem(items.first()); - } -} - -void KviChannelsJoinWindow::clearClicked() -{ - QString szCmd = "option stringlistRecentChannels"; - - KviConsoleWindow * c = g_pApp->topmostConnectedConsole(); - if(!c) - return; // no connection - - KviWindow * w = g_pActiveWindow; - if(w->console() != c) - w = c; - - KviKvsScript::run(szCmd,w); - fillListView(); -} - -/* -void KviChannelsJoinWindow::whoClicked() -{ - KviCString tmp = m_pChannelEdit->text(); - if(!tmp.isEmpty())doCmd("who", tmp.ptr()); -} - -void KviChannelsJoinWindow::namesClicked() -{ - KviCString tmp = m_pChannelEdit->text(); - //FIXME: I must be a nice guy and implement /names in the core... - if(!tmp.isEmpty())doCmd("raw names", tmp.ptr()); -} - -void KviChannelsJoinWindow::itemDoubleClicked(KviTalListBoxItem * it) -{ - if (it == 0)return; - KviCString tmp = it->text(); - doCmd("join", tmp.ptr()); -// if(KVI_OPTION_BOOL(KviOption_boolCloseChannelsJoinAfterJoin)) -// g_pApp->collectGarbage(this); -} -*/ - -void KviChannelsJoinWindow::editReturnPressed() -{ - joinClicked(); -} - -void KviChannelsJoinWindow::closeEvent(QCloseEvent * e) -{ - e->ignore(); - delete this; -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_channelsjoinwindow.moc" -#endif //COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/channelsjoin/channelsjoinwindow.h b/src/modules/channelsjoin/channelsjoinwindow.h deleted file mode 100644 index ee819f4cd..000000000 --- a/src/modules/channelsjoin/channelsjoinwindow.h +++ /dev/null @@ -1,162 +0,0 @@ -#ifndef _CHANNELSJOIN_H_ -#define _CHANNELSJOIN_H_ -//============================================================================= -// -// File : channelsjoinwindow.h -// Creation date : Thu Nov 06 2001 12:30:25 CEST by Juan Alvarez -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -/** -* \file channelsjoinwindow.h -* \author Juan Alvarez -* \brief Channels join window -*/ - -#include "KviWindow.h" -#include "KviCString.h" -#include - -#include - -class QCheckBox; -class QPushButton; -class QLineEdit; -class KviConsoleWindow; -class KviTalGroupBox; - -/** -* \class KviChannelsJoinWindow -* \brief Channels join window class -*/ -class KviChannelsJoinWindow : public QDialog -{ - Q_OBJECT -public: - /** - * \brief Constructs the channels join window - * \param par The parent widget - * \param name The name of the window - * \return KviChannelsJoinWindow - */ - KviChannelsJoinWindow(QWidget * par, const char * name); - - /** - * \brief Destroys the channels join window - */ - ~KviChannelsJoinWindow(); -protected: - QLineEdit * m_pChannelEdit; - QTreeWidget * m_pTreeWidget; - KviTalGroupBox * m_pGroupBox; - QLineEdit * m_pPass; - QCheckBox * m_pShowAtStartupCheck; - QCheckBox * m_pCloseAfterJoinCheck; - QPushButton * m_pJoinButton; - QPushButton * m_pRegButton; - QPushButton * m_pClearButton; - KviConsoleWindow * m_pConsole; -public: - virtual void closeEvent(QCloseEvent * e); - - /** - * \brief Fills in the servers' list - * \return void - */ - void fillListView(); - - /** - * \brief Enables join and register button if channel is found - * \return void - */ - void enableJoin(); - - /** - * \brief Sets the console and fills in the servers' list - * \param pConsole The source console - * \return void - */ - void setConsole(KviConsoleWindow * pConsole); -protected slots: - /** - * \brief Called when the text changes - * \return void - */ - void editTextChanged(const QString &); - - /** - * \brief Called when an item is clicked - * \param it The item clicked - * \return void - */ - void itemClicked(QTreeWidgetItem * it, int); - - /** - * \brief Called when an item is double-clicked - * \param it The item clicked - * \return void - */ - void itemDoubleClicked(QTreeWidgetItem * it, int); - - /** - * \brief Called when the return is pressed - * - * It joins the selected channel - * \return void - */ - void editReturnPressed(); - - /** - * \brief Called when the cancel button is pressed - * - * It destroys the window object - * \return void - */ - void cancelClicked(); - - /** - * \brief Called when the join button is pressed - * - * It joins the selected channel - * \return void - */ - void joinClicked(); - - /** - * \brief Called when the register button is pressed - * - * It registers the selected channel in the database - * \return void - */ - void regClicked(); - - /** - * \brief Called when the clear button is pressed - * - * It clears the list of recent channels - * \return void - */ - void clearClicked(); - - //void whoClicked(); - //void namesClicked(); -}; - -#endif //_CHANNELSJOINSWINDOW_H_ diff --git a/src/modules/channelsjoin/libkvichannelsjoin.cpp b/src/modules/channelsjoin/libkvichannelsjoin.cpp index 4f602a2e3..a96c3dc86 100644 --- a/src/modules/channelsjoin/libkvichannelsjoin.cpp +++ b/src/modules/channelsjoin/libkvichannelsjoin.cpp @@ -22,7 +22,7 @@ // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // //============================================================================= -#include "channelsjoinwindow.h" +#include "ChannelsJoinDialog.h" #include "KviModule.h" #include "KviWindow.h" @@ -32,7 +32,7 @@ #include -KviChannelsJoinWindow * g_pChannelsWindow = 0; +ChannelsJoinDialog * g_pChannelsWindow = 0; QRect g_rectChannelsJoinGeometry; /* @@ -53,7 +53,7 @@ QRect g_rectChannelsJoinGeometry; static bool channelsjoin_kvs_cmd_open(KviKvsModuleCommandCall * c) { - if(!g_pChannelsWindow)g_pChannelsWindow = new KviChannelsJoinWindow(c->window()->frame(),"channelsjoin"); + if(!g_pChannelsWindow)g_pChannelsWindow = new ChannelsJoinDialog(c->window()->frame(),"channelsjoin"); g_pChannelsWindow->setConsole(c->window()->console()); diff --git a/src/modules/classeditor/CMakeLists.txt b/src/modules/classeditor/CMakeLists.txt index 94a459d5b..eb2d56d84 100644 --- a/src/modules/classeditor/CMakeLists.txt +++ b/src/modules/classeditor/CMakeLists.txt @@ -1,12 +1,12 @@ # CMakeLists for src/modules/classeditor SET(kviclasseditor_MOC_HDRS - classeditor.h + ClassEditorWindow.h ) SET(kviclasseditor_SRCS libkviclasseditor.cpp - classeditor.cpp + ClassEditorWindow.cpp ) # After this call, files will be moc'ed to moc_kvi_*.cpp diff --git a/src/modules/classeditor/ClassEditorWindow.cpp b/src/modules/classeditor/ClassEditorWindow.cpp new file mode 100644 index 000000000..95ae67111 --- /dev/null +++ b/src/modules/classeditor/ClassEditorWindow.cpp @@ -0,0 +1,2101 @@ +//============================================================================= +// +// File : ClassEditorWindow.cpp +// Creation date : Mon Feb 15 2010 14:35:55 CEST by Carbone Alessandro +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2010 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the linkss of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include "ClassEditorWindow.h" + +#include "KviIconManager.h" +#include "KviOptions.h" +#include "KviLocale.h" +#include "KviImageDialog.h" +#include "KviConfigurationFile.h" +#include "KviFileDialog.h" +#include "KviFileUtils.h" +#include "KviScriptEditor.h" +#include "kvi_debug.h" +#include "KviApplication.h" +#include "KviMainWindow.h" +#include "KviQString.h" +#include "KviKvsKernel.h" +#include "KviKvsObjectClass.h" +#include "KviKvsObjectController.h" +#include "KviFileDialog.h" +#include "KviCommandFormatter.h" +#include "KviModule.h" +#include "KviTalVBox.h" +#include "kvi_fileextensions.h" +#include "KviModuleManager.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern ClassEditorWindow * g_pClassEditorWindow; +extern KviModule * g_pClassEditorModule; + +ClassEditorTreeWidget::ClassEditorTreeWidget(QWidget * pParent) +: QTreeWidget(pParent) +{ + setColumnCount (1); + setHeaderLabel(__tr2qs_ctx("Class","editor")); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setSortingEnabled(true); + setRootIsDecorated(true); + setAnimated(true); +} + +ClassEditorTreeWidget::~ClassEditorTreeWidget() +{ + //remove and delete all items + clear(); +} + +void ClassEditorTreeWidget::mousePressEvent(QMouseEvent * e) +{ + if(e->button() == Qt::RightButton) + { + QTreeWidgetItem * pItem = itemAt(e->pos()); + if(pItem) + emit rightButtonPressed(pItem,QCursor::pos()); + } + QTreeWidget::mousePressEvent(e); +} + +ClassEditorTreeWidgetItem::ClassEditorTreeWidgetItem(QTreeWidget * pTreeWidget, Type eType, const QString & szName) +: QTreeWidgetItem(pTreeWidget), KviHeapObject(), m_eType(eType) +{ + setName(szName); + m_szInheritsClassName = ""; + m_iPos = 0; + m_bInternal = false; + m_bClassModified = false; + QPixmap * pIcon = 0; + + if(eType == ClassEditorTreeWidgetItem::Namespace) + pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE); + else + pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASS); + + setIcon(0,QIcon(*pIcon)); +} + +ClassEditorTreeWidgetItem::ClassEditorTreeWidgetItem(ClassEditorTreeWidgetItem * pParentItem, Type eType, const QString & szName) +: QTreeWidgetItem(pParentItem), m_eType(eType) +{ + setFlags(Qt::ItemIsEditable|Qt::ItemIsEnabled|Qt::ItemIsSelectable); + setName(szName); + m_szInheritsClassName = ""; + m_bInternal = false; + m_iPos = 0; + m_bClassModified = false; + QPixmap * pIcon = 0; + + if(eType == ClassEditorTreeWidgetItem::Namespace) + pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE); + else if(eType == ClassEditorTreeWidgetItem::Class) + pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASS); + else + pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_FUNCTION); + + setIcon(0,QIcon(*pIcon)); +} + +void ClassEditorTreeWidgetItem::setClassNotBuilt(bool bModified) +{ + m_bClassModified = bModified; + QPixmap * pIcon = 0; + + if(bModified) + pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASSNOTBUILT); + else + pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASS); + + setIcon(0,QIcon(*pIcon)); +} + +void ClassEditorTreeWidgetItem::setName(const QString & szName) +{ + m_szName = szName; + setText(0,m_szName); +} + +void ClassEditorTreeWidgetItem::setType(Type eType) +{ + m_eType = eType; + QPixmap * pIcon = 0; + + if(eType == ClassEditorTreeWidgetItem::Namespace) + pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE); + else if(eType == ClassEditorTreeWidgetItem::Class) + pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASS); + else + pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_FUNCTION); + + setIcon(0,QIcon(*pIcon)); +} + +ClassEditorWidget::ClassEditorWidget(QWidget * pParent) +: QWidget(pParent) +{ + m_pClasses = new KviPointerHashTable(100,false); + m_pClasses->setAutoDelete(false); + m_pLastEditedItem = 0; + m_pLastClickedItem = 0; + m_szDir = QDir::homePath(); + + QGridLayout * pLayout = new QGridLayout(this); + + m_pSplitter = new QSplitter(Qt::Horizontal,this); + m_pSplitter->setChildrenCollapsible(false); + pLayout->addWidget(m_pSplitter,0,0); + + KviTalVBox * pVBox = new KviTalVBox(m_pSplitter); + pVBox->setSpacing(0); + pVBox->setMargin(0); + m_pTreeWidget = new ClassEditorTreeWidget(pVBox); + + pVBox = new KviTalVBox(m_pSplitter); + + KviTalHBox * pHBox = new KviTalHBox(pVBox); + pHBox->setSpacing(0); + pHBox->setMargin(0); + m_pClassNameLabel = new QLabel(__tr2qs_ctx("No item selected","editor"),pHBox); + pHBox->setStretchFactor(m_pClassNameLabel,2); + m_pClassNameLabel->setWordWrap(true); + m_pClassNameRenameButton = new QPushButton(__tr2qs_ctx("Rename","editor"),pHBox); + m_pClassNameRenameButton->setToolTip(__tr2qs_ctx("Edit the class or namespace name","editor")); + m_pClassNameRenameButton->setEnabled(false); + connect(m_pClassNameRenameButton,SIGNAL(clicked()),this,SLOT(renameItem())); + + pHBox = new KviTalHBox(pVBox); + pHBox->setSpacing(0); + pHBox->setMargin(0); + + pHBox = new KviTalHBox(pVBox); + pHBox->setSpacing(0); + pHBox->setMargin(0); + m_pFunctionNameLabel = new QLabel(__tr2qs_ctx("No item selected","editor"),pHBox); + pHBox->setStretchFactor(m_pFunctionNameLabel,2); + m_pFunctionNameRenameButton = new QPushButton(__tr2qs_ctx("Rename","editor"),pHBox); + m_pFunctionNameRenameButton->setToolTip(__tr2qs_ctx("Edit the function member name","editor")); + m_pFunctionNameRenameButton->setEnabled(false); + connect(m_pFunctionNameRenameButton,SIGNAL(clicked()),this,SLOT(renameFunction())); + + m_pReminderLabel = new QLabel(__tr2qs_ctx("No item selected","editor"),pVBox); + m_pReminderLabel->hide(); + m_pReminderLabel->setWordWrap(true); + + m_pEditor = KviScriptEditor::createInstance(pVBox); + m_pEditor->setFocus(); + connect(m_pEditor,SIGNAL(find(const QString &)),this,SLOT(slotFindWord(const QString &))); + connect(m_pEditor,SIGNAL(replaceAll(const QString &,const QString &)),this,SLOT(slotReplaceAll(const QString &,const QString &))); + m_pContextPopup = new KviTalPopupMenu(this); + + oneTimeSetup(); + + currentItemChanged(0,0); +} + +ClassEditorWidget::~ClassEditorWidget() +{ + m_pClasses->clear(); + delete m_pClasses; +} + +void ClassEditorWidget::buildFullItemPath(ClassEditorTreeWidgetItem * pItem, QString & szBuffer) +{ + if(!pItem) + return; + szBuffer.prepend(pItem->name() + "::"); + pItem = (ClassEditorTreeWidgetItem *)pItem->parent(); + while(pItem) + { + QString szTmp = pItem->name(); + if(!szTmp.isEmpty()) + { + szBuffer.prepend("::"); + szBuffer.prepend(szTmp); + } + pItem = (ClassEditorTreeWidgetItem *)pItem->parent(); + } +} + +QString ClassEditorWidget::buildFullClassName(ClassEditorTreeWidgetItem * pItem) +{ + if(!pItem) + return QString(); + QString szName = pItem->name(); + ClassEditorTreeWidgetItem * pNItem = (ClassEditorTreeWidgetItem *)pItem->parent(); + while(pNItem) + { + QString szTmp = pNItem->name(); + if(!szTmp.isEmpty()) + { + szName.prepend("::"); + szName.prepend(szTmp); + } + pNItem = (ClassEditorTreeWidgetItem *)pNItem->parent(); + } + return szName; +} + +ClassEditorTreeWidgetItem * ClassEditorWidget::findTopLevelItem(const QString & szName) +{ + for(int i=0; i < m_pTreeWidget->topLevelItemCount(); i++) + { + if(KviQString::equalCI(m_pTreeWidget->topLevelItem(i)->text(0),szName)) + return (ClassEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i); + } + return 0; +} + +ClassEditorTreeWidgetItem * ClassEditorWidget::findItem(const QString & szFullName) +{ + bool bFound; + QStringList lNamespaces = szFullName.split("::"); + if(lNamespaces.count() == 0) + return 0; + ClassEditorTreeWidgetItem * pItem = findTopLevelItem(lNamespaces.at(0)); + if(!pItem) + return 0; + + for(int i=1; i < lNamespaces.count(); i++) + { + bFound = false; + for(int j=0; j < pItem->childCount(); j++) + { + if (KviQString::equalCI(pItem->child(j)->text(0),lNamespaces.at(i))) + { + pItem=( ClassEditorTreeWidgetItem *)pItem->child(j); + bFound = true; + break; + } + } + if(!bFound) + return 0; + } + return (ClassEditorTreeWidgetItem *)pItem; +} + +ClassEditorTreeWidgetItem * ClassEditorWidget::createFullItem(const QString & szFullName) +{ + bool bFound; + int i; + + QStringList lNamespaces = szFullName.split("::"); + if(lNamespaces.count() == 0) + return 0; + if(lNamespaces.count() == 1) + { + ClassEditorTreeWidgetItem * pItem = findTopLevelItem(lNamespaces.at(0)); + if(pItem) + return pItem; + return new ClassEditorTreeWidgetItem(m_pTreeWidget,ClassEditorTreeWidgetItem::Class,lNamespaces.at(0)); + } + ClassEditorTreeWidgetItem * pItem = findTopLevelItem(lNamespaces.at(0)); + if(!pItem) + pItem = new ClassEditorTreeWidgetItem(m_pTreeWidget,ClassEditorTreeWidgetItem::Namespace,lNamespaces.at(0)); + + for(i=1; i < lNamespaces.count()-1; i++) + { + bFound = false; + for(int j=0; j < pItem->childCount();j++) + { + if(KviQString::equalCI(pItem->child(j)->text(0),lNamespaces.at(i))) + { + pItem = (ClassEditorTreeWidgetItem *)pItem->child(j); + bFound = true; + break; + } + } + if(!bFound) + pItem = new ClassEditorTreeWidgetItem(pItem,ClassEditorTreeWidgetItem::Namespace,lNamespaces.at(i)); + } + return new ClassEditorTreeWidgetItem(pItem,ClassEditorTreeWidgetItem::Class,lNamespaces.at(i)); +} + +ClassEditorTreeWidgetItem * ClassEditorWidget::createFullNamespace(const QString & szFullName) +{ + bool bFound; + int i; + + QStringList lNamespaces = szFullName.split("::"); + if(lNamespaces.count() == 0) + return 0; + ClassEditorTreeWidgetItem * pItem = findTopLevelItem(lNamespaces.at(0)); + if(!pItem) + pItem = new ClassEditorTreeWidgetItem(m_pTreeWidget,ClassEditorTreeWidgetItem::Namespace,lNamespaces.at(0)); + if(lNamespaces.count() == 1) + return pItem; + + for(i=1; i < lNamespaces.count(); i++) + { + bFound = false; + for(int j=0;jchildCount();j++) + { + if(KviQString::equalCI(pItem->child(j)->text(0),lNamespaces.at(i)) && (( ClassEditorTreeWidgetItem *)pItem->child(j))->isNamespace()) + { + pItem = (ClassEditorTreeWidgetItem *)pItem->child(j); + bFound = true; + break; + } + } + if(!bFound) + pItem = new ClassEditorTreeWidgetItem(pItem,ClassEditorTreeWidgetItem::Namespace,lNamespaces.at(i)); + } + return pItem; +} + +void ClassEditorWidget::oneTimeSetup() +{ + QStringList sl; + QString szClassName; + QString szPath; + g_pApp->getLocalKvircDirectory(szPath,KviApplication::Classes); + QDir d(szPath); + + QString szExtension = QString("*%1").arg(KVI_FILEEXTENSION_SCRIPT); // *.kvs + sl = d.entryList(QStringList(szExtension), QDir::Files | QDir::NoDotAndDotDot); + + g_pModuleManager->getModule("objects"); + KviPointerHashTableIterator it(*KviKvsKernel::instance()->objectController()->classDict()); + + KviKvsObjectClass * pClass = 0; + ClassEditorTreeWidgetItem * pClassItem = 0; + while(KviKvsObjectClass * pClass = it.current()) + { + if(pClass->isBuiltin()) + m_pClasses->insert(it.currentKey(),0); + else + { + QString szTmp; + szTmp = it.currentKey(); + szTmp.replace("::","--"); + szTmp.append(".kvs"); + if(sl.indexOf(szTmp) == -1) + { + szClassName = it.currentKey(); + pClassItem = createFullItem(szClassName); + createFullClass(it.current(),pClassItem,szClassName); + } + } + ++it; + } + + for(int i=0; i < sl.count(); i++) + { + szClassName = sl.at(i); + szClassName.replace("--","::"); + szClassName.chop(4); + pClassItem = createFullItem(szClassName); + pClass = KviKvsKernel::instance()->objectController()->lookupClass(szClassName); + if(pClass) + createFullClass(pClass, pClassItem, szClassName); + } + loadNotBuiltClasses(); + connect(m_pTreeWidget,SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),this,SLOT(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *))); + m_pTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_pTreeWidget,SIGNAL(customContextMenuRequested(const QPoint &)),this,SLOT(customContextMenuRequested(const QPoint &))); +} + +void ClassEditorWidget::createFullClass(KviKvsObjectClass * pClass, ClassEditorTreeWidgetItem * pClassItem, const QString & szClassName) +{ + KviPointerHashTableIterator it(* pClass->getHandlers()); + QStringList szFunctionsList; + while(it.current()) + { + szFunctionsList.append(it.currentKey()); + ++it; + } + szFunctionsList.sort(); + ClassEditorTreeWidgetItem *pFunctionItem; + m_pClasses->insert(szClassName,pClassItem); + KviKvsObjectClass * pParentClass = pClass->parentClass(); + pClassItem->setInheritsClass(pParentClass->name()); + for(int i=0;ilookupFunctionHandler(szFunctionsList.at(i)); + if (pClass->isScriptHandler(szFunctionsList.at(i)) && !pHandler->isClone()) + { + pFunctionItem=findFunction(szFunctionsList.at(i), pClassItem); + if(!pFunctionItem) pFunctionItem = new ClassEditorTreeWidgetItem(pClassItem,ClassEditorTreeWidgetItem::Method,szFunctionsList.at(i)); + pClass->getFunctionCode(szCode,*pHandler); + pFunctionItem->setBuffer(szCode); + pFunctionItem->setReminder(pClass->reminder(pHandler)); + if(pHandler->flags() & KviKvsObjectFunctionHandler::Internal) + pFunctionItem->setInternalFunction(true); + } + //++it; + } +} + + +/* +void ClassEditorWidget::classRefresh(const QString & szName) +{ + if(m_bSaving) + return; + ClassEditorTreeWidgetItem * item; + KviKvsScript * class = KviKvsClassManager::instance()->classDict()->find(szName); + item = createFullItem(szName); + if(item!=m_pLastEditedItem) + { + item->setBuffer(class->code()); + return; + } + if( + QMessageBox::warning(0,__tr2qs_ctx("OverWrite Current Class","editor"), + __tr2qs_ctx("An external script has changed the class you are currently editing. Do you want to accept the external changes?","editor"), + QMessageBox::Yes,QMessageBox::No|QMessageBox::Default|QMessageBox::Escape) != QMessageBox::Yes + ) + return; + item->setBuffer(class->code()); + m_pEditor->setText(class->code()); +} +*/ + +bool ClassEditorWidget::hasSelectedItems() +{ + return m_pTreeWidget->selectedItems().count() ? 1 : 0; +} + +bool ClassEditorWidget::classExists(QString & szFullItemName) +{ + if(m_pClasses->find(szFullItemName)) + return true; + else + return false; +} + +void ClassEditorWidget::renameFunction() +{ + if(!m_pLastEditedItem) + return; + ClassEditorTreeWidgetItem * pFunction = m_pLastEditedItem; + QString szClassName = buildFullClassName((ClassEditorTreeWidgetItem *)pFunction->parent()); + QString szFunctionName = pFunction->name(); + QString szReminder = pFunction->reminder(); + QString szNewReminder = szReminder; + ClassEditorTreeWidgetItem * pParentClass = (ClassEditorTreeWidgetItem *) pFunction->parent(); + + QString szNewFunctionName = szFunctionName; + bool bInternal = pFunction->isInternalFunction(); + if(!askForFunction(szNewFunctionName,szNewReminder,&bInternal,szClassName,true)) + return; + if(KviQString::equalCS(szFunctionName,szNewFunctionName) && bInternal == pFunction->isInternalFunction()) + { + if(!KviQString::equalCS(szNewReminder,szReminder)) + { + pFunction->setReminder(szNewReminder); + KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(szClassName); + if(pClass) + { + KviKvsObjectFunctionHandler * pHandler = pClass->lookupFunctionHandler(szFunctionName); + if(pHandler) + { + pClass->setReminder(szNewReminder,pHandler); + QString szPath; + QString szFileName = szClassName.toLower(); + szFileName += ".kvs"; + szFileName.replace("::","--"); + g_pApp->getLocalKvircDirectory(szPath,KviApplication::Classes,szFileName); + pClass->save(szPath); + } + } + currentItemChanged(pFunction,pFunction); + } else { + g_pClassEditorModule->lock(); + QMessageBox::information(this, + __tr2qs_ctx("Function already exists","editor"), + __tr2qs_ctx("This name is already in use. Please choose another one.","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + g_pClassEditorModule->unlock(); + return; + } + } + + pFunction->setName(szNewFunctionName); + pFunction->setReminder(szNewReminder); + currentItemChanged(pFunction,pFunction); + pFunction->setInternalFunction(bInternal); + pParentClass->setClassNotBuilt(true); + + KviPointerList lInheritedClasses; + lInheritedClasses.setAutoDelete(false); + searchInheritedClasses(szClassName,lInheritedClasses); + for(unsigned int i=0; i < lInheritedClasses.count(); i++) + lInheritedClasses.at(i)->setClassNotBuilt(true); + activateItem(pFunction); +} + +ClassEditorTreeWidgetItem * ClassEditorWidget::findFunction(const QString & szFunctionName, ClassEditorTreeWidgetItem * pClass) +{ + for(int i=0; i < pClass->childCount(); i++) + { + if(KviQString::equalCI(szFunctionName,((ClassEditorTreeWidgetItem *)pClass->child(i))->name())) + return (ClassEditorTreeWidgetItem *) pClass->child(i); + } + return 0; +} + +void ClassEditorWidget::renameItem() +{ + if(!m_pLastEditedItem) + return; + if(m_pLastEditedItem->isClass()) + renameClass(m_pLastEditedItem); + else if(m_pLastEditedItem->isNamespace()) + renameNamespace(m_pLastEditedItem); + else { + // is function + ClassEditorTreeWidgetItem * pParent = (ClassEditorTreeWidgetItem *)m_pLastEditedItem->parent(); + if(pParent->isClass()) + renameClass(pParent); + } +} + +void ClassEditorWidget::renameClass(ClassEditorTreeWidgetItem * pClassItem) +{ + QString szClassName = buildFullClassName(pClassItem); + QString szNewClassName = szClassName; + + QString szInheritsClassName = pClassItem->inheritsClass(); + QString szNewInheritsClassName = szInheritsClassName; + bool bOk = askForClassName(szNewClassName,szNewInheritsClassName,true); + if(!bOk) + return; + if(classExists(szNewClassName) && KviQString::equalCS(szClassName,szNewClassName) && KviQString::equalCS(szInheritsClassName,szNewInheritsClassName)) + { + g_pClassEditorModule->lock(); + QMessageBox::information(this, + __tr2qs_ctx("Class already exists","editor"), + __tr2qs_ctx("This name is already in use. Please choose another one.","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + g_pClassEditorModule->unlock(); + return; + } + /*if(szNewClassName.tmp.indexOf("@@",Qt::CaseInsensitive) != -1) + { + g_pClassEditorModule->lock(); + QMessageBox::information(this, + __tr2qs_ctx("Bad Namespace Name","editor"), + __tr2qs_ctx("Found an empty namespace in namespace name","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + g_pClassEditorModule->unlock(); + szNewName = ""; + continue; + }*/ + ClassEditorTreeWidgetItem * pNewItem = 0; + m_pClasses->removeRef(pClassItem); + cutItem(pClassItem); + if(szNewClassName.contains("::")) + { + pNewItem = createFullNamespace(szNewClassName.left(szNewClassName.lastIndexOf("::"))); + pClassItem->setName(szNewClassName.section("::",-1,-1)); + pNewItem->addChild(pClassItem); + } else { + pClassItem->setName(szNewClassName); + m_pTreeWidget->addTopLevelItem(pClassItem); + } + m_pClasses->insert(szNewClassName,pClassItem); + pClassItem->setInheritsClass(szNewInheritsClassName); + pClassItem->setClassNotBuilt(true); + + KviPointerList lInheritedClasses; + lInheritedClasses.setAutoDelete(false); + searchInheritedClasses(szClassName,lInheritedClasses); + for(unsigned int i=0; i < lInheritedClasses.count(); i++) + { + lInheritedClasses.at(i)->setClassNotBuilt(true); + lInheritedClasses.at(i)->setExpanded(true); + lInheritedClasses.at(i)->setInheritsClass(szNewClassName); + } + + if(pNewItem) + { + activateItem(pNewItem); + pNewItem->setExpanded(true); + } else { + activateItem(pClassItem); + pClassItem->setExpanded(true); + } + + qDebug("delete class %s caused by rename",szClassName.toUtf8().data()); + KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(szClassName); + if(pClass) + KviKvsKernel::instance()->objectController()->deleteClass(pClass); +} + +void ClassEditorWidget::cutItem(ClassEditorTreeWidgetItem * pItem) +{ + int iIdx = m_pTreeWidget->indexOfTopLevelItem(pItem); + if(iIdx!=-1) + m_pTreeWidget->takeTopLevelItem(iIdx); + else { + ClassEditorTreeWidgetItem * pParent = (ClassEditorTreeWidgetItem *)pItem->parent(); + pParent->removeChild(pItem); + } +} + +void ClassEditorWidget::renameNamespace(ClassEditorTreeWidgetItem * pOldNamespaceItem) +{ + QString szOldNameSpaceName = buildFullClassName(m_pLastEditedItem); + QString szNewNameSpaceName; + if(!askForNamespaceName(__tr2qs_ctx("Rename Namespace","editor"),__tr2qs_ctx("Please enter the new name for the namespace","editor"),szOldNameSpaceName,szNewNameSpaceName)) + return; + if(KviQString::equalCI(szOldNameSpaceName,szNewNameSpaceName)) + return; + ClassEditorTreeWidgetItem * pNewItem = findItem(szNewNameSpaceName); + if(pNewItem) + { + g_pClassEditorModule->lock(); + if(pNewItem->isClass()) + { + QMessageBox::information(this, + __tr2qs_ctx("Name already exists as Class name","editor"), + __tr2qs_ctx("This name is already in use as Class name. Please choose another one.","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + } else { + QMessageBox::information(this, + __tr2qs_ctx("Namespace already exists","editor"), + __tr2qs_ctx("This name is already in use. Please choose another one.","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + } + g_pClassEditorModule->unlock(); + return; + } + KviPointerList pList; + pList.setAutoDelete(false); + appendAllClassItemsRecursive(&pList,pOldNamespaceItem); + cutItem(pOldNamespaceItem); + if(szNewNameSpaceName.contains("::")) + { + pNewItem=createFullNamespace(szNewNameSpaceName.left(szNewNameSpaceName.lastIndexOf("::"))); + pOldNamespaceItem->setName(szNewNameSpaceName.section("::",-1,-1)); + pNewItem->addChild(pOldNamespaceItem); + } else { + m_pTreeWidget->addTopLevelItem(pOldNamespaceItem); + pOldNamespaceItem->setName(szNewNameSpaceName); + } + for(unsigned int u=0; u < pList.count(); u++) + { + KviPointerHashTableEntry * pEntry = m_pClasses->findRef(pList.at(u)); + if(pEntry) + { + KviPointerList lInheritedClasses; + lInheritedClasses.setAutoDelete(false); + + QString szOldName = pEntry->key(); + QString szNewName = buildFullClassName(pList.at(u)); + searchInheritedClasses(szOldName,lInheritedClasses); + for(unsigned int v=0; v < lInheritedClasses.count(); v++) + { + lInheritedClasses.at(v)->setClassNotBuilt(true); + lInheritedClasses.at(v)->setExpanded(true); + lInheritedClasses.at(v)->setInheritsClass(szNewName); + } + m_pClasses->removeRef(pList.at(u)); + m_pClasses->insert(szNewName,pList.at(u)); + pList.at(u)->setClassNotBuilt(true); + + KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(szOldName); + if(pClass) + KviKvsKernel::instance()->objectController()->deleteClass(pClass); + } + } + + if(pNewItem) + { + activateItem(pNewItem); + pNewItem->setExpanded(true); + } else { + activateItem(pOldNamespaceItem); + pOldNamespaceItem->setExpanded(true); + } + //searchReplace(szOldNameSpaceName+"::",true,szNewNameSpaceName+"::"); +} + +void ClassEditorWidget::saveLastEditedItem() +{ + if(!m_pLastEditedItem) + return; + if(!m_pEditor->isModified() || m_pLastEditedItem->isNamespace() || m_pLastEditedItem->isClass()) + return; + ((ClassEditorTreeWidgetItem *)m_pLastEditedItem)->setCursorPosition(m_pEditor->getCursor()); + QString newCode; + m_pEditor->getText(newCode); + ((ClassEditorTreeWidgetItem *)m_pLastEditedItem)->setBuffer(newCode); + ((ClassEditorTreeWidgetItem *)m_pLastEditedItem->parent())->setClassNotBuilt(true); +} + +void ClassEditorWidget::currentItemChanged(QTreeWidgetItem * pTree, QTreeWidgetItem *) +{ + saveLastEditedItem(); + m_pLastEditedItem = (ClassEditorTreeWidgetItem *)pTree; + if(!m_pLastEditedItem) + { + m_pClassNameLabel->setText(__tr2qs_ctx("No item selected","editor")); + m_pClassNameRenameButton->setEnabled(false); + m_pEditor->setText(""); + m_pEditor->setEnabled(false); + return; + } + + ClassEditorTreeWidgetItem * pClassItem = 0; + if(m_pLastEditedItem->isMethod()) + pClassItem = (ClassEditorTreeWidgetItem *)m_pLastEditedItem->parent(); + else + pClassItem = m_pLastEditedItem; + + QString szClassName = buildFullClassName(pClassItem); + + if(m_pLastEditedItem->isNamespace()) + { + QString szLabelText = __tr2qs_ctx("Namespace","editor"); + szLabelText += ": "; + szLabelText += szClassName; + szLabelText += ""; + m_pClassNameLabel->setText(szLabelText); + m_pClassNameRenameButton->setEnabled(true); + m_pFunctionNameRenameButton->setEnabled(false); + //m_pinheritsClassNameLabel->setText(""); + m_pFunctionNameLabel->setText(""); + m_pEditor->setText(""); + m_pEditor->setEnabled(false); + m_pTreeWidget->setFocus(); + return; + } + + QString szLabelText = __tr2qs_ctx("Class","editor"); + szLabelText += ": "; + szLabelText += szClassName; + szLabelText += ", "; + szLabelText += __tr2qs_ctx("inherits from class ","editor"); + szLabelText += ": "; + szLabelText += pClassItem->inheritsClass(); + szLabelText += ""; + m_pClassNameLabel->setText(szLabelText); + + szLabelText = __tr2qs_ctx("Member Function","editor"); + if(m_pLastEditedItem->isMethod()) + { + szLabelText += ": "; + szLabelText += m_pLastEditedItem->text(0); + szLabelText += ""; + m_pFunctionNameRenameButton->setEnabled(true); + if(m_pLastEditedItem->reminder().isEmpty()) + m_pReminderLabel->hide(); + else { + QString szReminderText =__tr2qs_ctx("Reminder text.","editor"); + szReminderText += ": "; + szReminderText += m_pLastEditedItem->reminder(); + szReminderText += ""; + m_pReminderLabel->setText(szReminderText); + m_pReminderLabel->show(); + } + + m_pFunctionNameLabel->setText(szLabelText); + m_pFunctionNameLabel->show(); + m_pFunctionNameRenameButton->show(); + } else { + m_pReminderLabel->hide(); + m_pFunctionNameLabel->hide(); + m_pClassNameRenameButton->setEnabled(true); + m_pFunctionNameRenameButton->hide(); + } + if(m_pLastEditedItem->isClass()) + { + m_pFunctionNameRenameButton->setEnabled(false); + m_pEditor->setText(""); + m_pEditor->setEnabled(true); + m_pTreeWidget->setFocus(); + QString szBuffer; + QStringList szFunctionsList; + KviPointerHashTable lFunctions; + lFunctions.setAutoDelete(false); + + ClassEditorTreeWidgetItem * pItem = 0; + for(int i=0; i < pTree->childCount(); i++) + { + pItem = ((ClassEditorTreeWidgetItem *)pTree->child(i)); + szFunctionsList.append(pItem->name()); + lFunctions.insert(pItem->name(),pItem); + } + szFunctionsList.sort(); + for(int i=0; i < szFunctionsList.count(); i++) + { + szBuffer += "Member Function: $" + szFunctionsList.at(i) + "
"; + if(!lFunctions.find(szFunctionsList.at(i))->reminder().isEmpty()) + szBuffer+="Parameters reminder: "+lFunctions.find(szFunctionsList.at(i))->reminder()+"
"; + szBuffer+="
"; + } + m_pEditor->setUnHighlightedText(szBuffer); + m_pEditor->setReadOnly(true); + return; + } + m_pEditor->setReadOnly(false); + m_pEditor->setText(((ClassEditorTreeWidgetItem *)pTree)->buffer()); + m_pEditor->setFocus(); + m_pEditor->setCursorPosition(((ClassEditorTreeWidgetItem *)pTree)->cursorPosition()); + m_pEditor->setEnabled(true); +} + +void ClassEditorWidget::customContextMenuRequested(QPoint pnt) +{ + m_pContextPopup->clear(); + + m_pLastClickedItem = (ClassEditorTreeWidgetItem *)m_pTreeWidget->itemAt(pnt); + + int iId; + iId = m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE)), + __tr2qs_ctx("Add Namespace","editor"), + this,SLOT(newNamespace())); + if(!m_pLastClickedItem) + m_pContextPopup->setItemEnabled(iId,true); + else + m_pContextPopup->setItemEnabled(iId,m_pLastClickedItem->isNamespace()); + + iId = m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASS)), + __tr2qs_ctx("Add Class","editor"), + this,SLOT(newClass())); + if(!m_pLastClickedItem) + m_pContextPopup->setItemEnabled(iId,true); + else + m_pContextPopup->setItemEnabled(iId,m_pLastClickedItem->isNamespace()); + + iId = m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FUNCTION)), + __tr2qs_ctx("Add Member Function","editor"), + this,SLOT(newMemberFunction())); + if(!m_pLastClickedItem) + m_pContextPopup->setItemEnabled(iId,false); + else + m_pContextPopup->setItemEnabled(iId,m_pLastClickedItem->isClass()| m_pLastClickedItem->isMethod()); + + bool bHasItems = m_pTreeWidget->topLevelItemCount(); + bool bHasSelected = hasSelectedItems(); + + m_pContextPopup->insertSeparator(); + + iId = m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)), + __tr2qs_ctx("Remove Selected","editor"), + this,SLOT(removeSelectedItems())); + m_pContextPopup->setItemEnabled(iId,bHasSelected); + + m_pContextPopup->insertSeparator(); + + m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)), + __tr2qs_ctx("Export Selected...","editor"), + this,SLOT(exportSelected())); + m_pContextPopup->setItemEnabled(iId,bHasSelected); + + m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)), + __tr2qs_ctx("Export Selected in singles files...","editor"), + this,SLOT(exportSelectedSepFiles())); + + m_pContextPopup->setItemEnabled(iId,bHasSelected); + + m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)), + __tr2qs_ctx("Export All...","editor"), + this,SLOT(exportAll())); + m_pContextPopup->setItemEnabled(iId,bHasItems); + + m_pContextPopup->insertSeparator(); + + m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_SEARCH)), + __tr2qs_ctx("Find In Classes...","editor"), + this,SLOT(slotFind())); + m_pContextPopup->setItemEnabled(iId,bHasItems); + + m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE)), + __tr2qs_ctx("Collapse All Items","editor"), + this,SLOT(slotCollapseItems())); + + m_pContextPopup->setItemEnabled(iId,bHasItems); + m_pContextPopup->popup(m_pTreeWidget->mapToGlobal(pnt)); +} + +void ClassEditorWidget::searchReplace(const QString & szSearch, bool bReplace, const QString & szReplace) +{ + KviPointerHashTableIterator it (*m_pClasses); + while(it.current()) + { + ClassEditorTreeWidgetItem * pItem = it.current(); + for(int j=0; j < pItem->childCount(); j++) + { + bool bOpened = false; + if(((ClassEditorTreeWidgetItem *)pItem->child(j))->buffer().indexOf(szSearch,0,Qt::CaseInsensitive) != -1) + { + pItem->child(j)->setBackground(0, QColor(255,0,0,128)); + if(bReplace) + { + QString &buffer=(QString &)((ClassEditorTreeWidgetItem *)pItem->child(j))->buffer(); + pItem->setClassNotBuilt(true); + buffer.replace(szSearch,szReplace,Qt::CaseInsensitive); + } + if(!bOpened) + { + openParentItems(pItem->child(j)); + bOpened = true; + } + } else { + pItem->child(j)->setBackground(0, QColor(255,255,255)); + } + } + ++it; + } +} + +void ClassEditorWidget::slotFind() +{ + g_pClassEditorModule->lock(); + bool bOk; + + QString szSearch = QInputDialog::getText(this, + __tr2qs_ctx("Find In Classes","editor"), + __tr2qs_ctx("Please enter the text to be searched for. The matching function will be highlighted.","editor"), + QLineEdit::Normal, + "", + &bOk); + + g_pClassEditorModule->unlock(); + if(!bOk) + return; + if(szSearch.isEmpty()) + return; + m_pEditor->setFindText(szSearch); + searchReplace(szSearch); +} + +void ClassEditorWidget::slotFindWord(const QString & szSearch) +{ + m_pEditor->setFindText(szSearch); +} + +void ClassEditorWidget::recursiveCollapseItems(ClassEditorTreeWidgetItem * pItem) +{ + if(!pItem) + return; + for(int i=0; i < pItem->childCount(); i++) + { + if(pItem->child(i)->childCount()) + { + pItem->child(i)->setExpanded(false); + recursiveCollapseItems((ClassEditorTreeWidgetItem *)pItem->child(i)); + } + } +} + +void ClassEditorWidget::slotCollapseItems() +{ + for(int i=0; i < m_pTreeWidget->topLevelItemCount(); i++) + { + if(m_pTreeWidget->topLevelItem(i)->childCount()) + { + m_pTreeWidget->topLevelItem(i)->setExpanded(false); + recursiveCollapseItems((ClassEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i)); + } + } +} + +void ClassEditorWidget::slotReplaceAll(const QString & szFind, const QString & szReplace) +{ + m_pEditor->setFindText(szReplace); + searchReplace(szFind,true,szReplace); + /* + for (int i=0;itopLevelItemCount();i++) + { + recursiveSearchReplace(szFind,(ClassEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i),true,szReplace); + } + */ +} + +void ClassEditorWidget::exportClassBuffer(QString & szBuffer, ClassEditorTreeWidgetItem * pItem) +{ + QString szTmp = pItem->buffer(); + KviCommandFormatter::blockFromBuffer(szTmp); + QString szName = buildFullClassName(pItem); + + szBuffer = "class(\""; + szBuffer += szName; + if(!pItem->inheritsClass().isEmpty()) + { + szBuffer += "\",\""; + szBuffer += pItem->inheritsClass(); + } + szBuffer += "\")\n{\n"; + for(int i=0; i < pItem->childCount(); i++) + { + ClassEditorTreeWidgetItem * pFunction = (ClassEditorTreeWidgetItem *)pItem->child(i); + if(pFunction->isMethod()) + { + szBuffer += "\t"; + if(pFunction->isInternalFunction()) + szBuffer += "internal "; + szBuffer += "function "; + szBuffer += pFunction->name(); + szBuffer += "(" + pFunction->reminder() + ")"; + szBuffer += "\n\t{\n"; + szBuffer += pFunction->buffer(); + szBuffer += "\n\t}\n"; + } + } + szBuffer += "}\n"; +} + +void ClassEditorWidget::exportAll() +{ + exportClasses(false); +} + +void ClassEditorWidget::exportSelectedSepFiles() +{ + exportClasses(true,true); +} + +void ClassEditorWidget::exportSelected() +{ + exportClasses(true); +} + +void ClassEditorWidget::exportSelectionInSinglesFiles(KviPointerList * pList) +{ + bool bReplaceAll = false; + + if(!m_szDir.endsWith(QString(KVI_PATH_SEPARATOR))) + m_szDir += KVI_PATH_SEPARATOR; + if(!pList->first()) + { + g_pClassEditorModule->lock(); + QMessageBox::warning(this,__tr2qs_ctx("Class Export","editor"),__tr2qs_ctx("There is no selection!","editor"),__tr2qs_ctx("OK","editor")); + g_pClassEditorModule->unlock(); + return; + } + g_pClassEditorModule->lock(); + + if(!KviFileDialog::askForDirectoryName(m_szDir,__tr2qs_ctx("Choose a Directory - KVIrc","editor"),m_szDir)) + { + g_pClassEditorModule->unlock(); + return; + } + + if(!m_szDir.endsWith(QString(KVI_PATH_SEPARATOR))) + m_szDir += KVI_PATH_SEPARATOR; + + for(ClassEditorTreeWidgetItem * pItem = pList->first(); pItem; pItem = pList->next()) + { + QString szTmp; + exportClassBuffer(szTmp,pItem); + QString szFileName = buildFullClassName(pItem); + szFileName += ".kvs"; + szFileName.replace("::","_"); + QString szCompletePath = m_szDir+szFileName; + if(KviFileUtils::fileExists(szCompletePath) && !bReplaceAll) + { + QString szMsg = __tr2qs_ctx("The file \"%1\" exists. Do you want to replace it?","editor").arg(szFileName); + int iRet = QMessageBox::question(this,__tr2qs_ctx("Replace file","editor"),szMsg,__tr2qs_ctx("Yes","editor"),__tr2qs_ctx("Yes to All","editor"),__tr2qs_ctx("No","editor")); + if(iRet != 2) + { + KviFileUtils::writeFile(szCompletePath,szTmp); + if(iRet == 1) + bReplaceAll = true; + } + } + else + KviFileUtils::writeFile(szCompletePath,szTmp); + } + g_pClassEditorModule->unlock(); +} + +void ClassEditorWidget::exportClasses(bool bSelectedOnly, bool bSingleFiles) +{ + QString szOut; + QString szNameFile; + QString szFile; + int iCount = 0; + + saveLastEditedItem(); + + KviPointerList list; + list.setAutoDelete(false); + + if(bSelectedOnly) + appendSelectedClassItems(&list); + else + appendAllClassItems(&list); + + if(bSingleFiles) + { + exportSelectionInSinglesFiles(&list); + return; + } + + ClassEditorTreeWidgetItem * pTempItem = 0; + for(ClassEditorTreeWidgetItem * pItem = list.first(); pItem; pItem = list.next()) + { + pTempItem = pItem; + iCount++; + QString szTmp; + exportClassBuffer(szTmp,pItem); + szOut += szTmp; + szOut += "\n"; + } + + if(szOut.isEmpty()) + { + g_pClassEditorModule->lock(); + QMessageBox::warning(this,__tr2qs_ctx("Class Export","editor"),__tr2qs_ctx("The exported file would be empty: cowardly refusing to write it","editor"),__tr2qs_ctx("OK","editor")); + g_pClassEditorModule->unlock(); + return; + } + + QString szName = m_szDir; + + if(!szName.endsWith(QString(KVI_PATH_SEPARATOR))) + szName += KVI_PATH_SEPARATOR; + + g_pClassEditorModule->lock(); + + if(iCount != 1) + szNameFile = "classes"; + else { + QString szTmp = buildFullClassName(pTempItem); + szNameFile = szTmp.replace("::","_"); + } + + szName += szNameFile; + szName += ".kvs"; + if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs_ctx("Choose a Filename - KVIrc","editor"),szName,KVI_FILTER_SCRIPT,false,true,true)) + { + g_pClassEditorModule->unlock(); + return; + } + m_szDir=QFileInfo(szFile).absolutePath(); + g_pClassEditorModule->unlock(); + + if(!KviFileUtils::writeFile(szFile,szOut)) + { + g_pClassEditorModule->lock(); + QMessageBox::warning(this,__tr2qs_ctx("Write Failed - KVIrc","editor"),__tr2qs_ctx("Unable to write to the class file.","editor"),__tr2qs_ctx("OK","editor")); + g_pClassEditorModule->unlock(); + } +} + +void ClassEditorWidget::saveProperties(KviConfigurationFile * pCfg) +{ + pCfg->writeEntry("Sizes",m_pSplitter->sizes()); + QString szName; + if(m_pLastEditedItem) + szName = buildFullClassName(m_pLastEditedItem); + pCfg->writeEntry("LastClass",szName); +} + +void ClassEditorWidget::loadProperties(KviConfigurationFile * pCfg) +{ + QList def; + def.append(20); + def.append(80); + m_pSplitter->setSizes(pCfg->readIntListEntry("Sizes",def)); + QString szTmp = pCfg->readEntry("LastClass",QString()); + + ClassEditorTreeWidgetItem * pItem = findItem(szTmp); + activateItem(pItem); +} + +void ClassEditorWidget::appendSelectedClassItems(KviPointerList * pList) +{ + QList list = m_pTreeWidget->selectedItems(); + for(int i=0; i < list.count(); i++) + { + if(((ClassEditorTreeWidgetItem *)list.at(i))->isClass()) + pList->append((ClassEditorTreeWidgetItem *)list.at(i)); + else appendSelectedClassItemsRecursive(pList,list.at(i)); + } +} + +void ClassEditorWidget::appendSelectedClassItemsRecursive(KviPointerList * pList, QTreeWidgetItem * pStartFrom) +{ + for(int i=0; i < pStartFrom->childCount(); i++) + { + if(((ClassEditorTreeWidgetItem *)pStartFrom->child(i))->isClass()) + pList->append(((ClassEditorTreeWidgetItem *)pStartFrom->child(i))); + else + appendSelectedClassItemsRecursive(pList,pStartFrom->child(i)); + } +} + +void ClassEditorWidget::appendAllClassItems(KviPointerList * pList) +{ + KviPointerHashTableIterator it (*m_pClasses); + while(it.current()) + { + pList->append(it.current()); + ++it; + } +} + +void ClassEditorWidget::appendAllClassItemsRecursive(KviPointerList * pList, QTreeWidgetItem * pStartFrom) +{ + for(int i=0; i < pStartFrom->childCount(); i++) + { + if(((ClassEditorTreeWidgetItem *)pStartFrom->child(i))->isClass()) + { + pList->append((ClassEditorTreeWidgetItem *)pStartFrom->child(i)); + } else { + appendAllClassItemsRecursive(pList,pStartFrom->child(i)); + } + } +} + +void ClassEditorWidget::removeItemChildren(ClassEditorTreeWidgetItem * pItem, KviPointerList & lRemovedItems) +{ + if(pItem->isClass()) + { + KviPointerList lInheritedClasses; + lInheritedClasses.setAutoDelete(false); + searchInheritedClasses(buildFullClassName(pItem),lInheritedClasses); + for(unsigned int u=0; u < lInheritedClasses.count(); u++) + { + lInheritedClasses.at(u)->setClassNotBuilt(true); + lInheritedClasses.at(u)->setExpanded(true); + lInheritedClasses.at(u)->setInheritsClass("object"); + } + } + + while(pItem->childCount() > 0) + { + ClassEditorTreeWidgetItem * pChild = (ClassEditorTreeWidgetItem *)(pItem->child(0)); + if(pChild->childCount()) + removeItemChildren(pChild,lRemovedItems); + if(pChild->isClass()) + { + m_pClasses->removeRef(pChild); + KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(buildFullClassName(pChild)); + if(pClass) + KviKvsKernel::instance()->objectController()->deleteClass(pClass); + qDebug("removing class %s %p",buildFullClassName(pChild).toUtf8().data(), pClass); + } + pItem->removeChild(pChild); + lRemovedItems.append(pItem); + delete pChild; + } +} + +bool ClassEditorWidget::removeItem(ClassEditorTreeWidgetItem * pItem, KviPointerList & lRemovedItems, bool * pbYesToAll) +{ + if(!pItem) + return true; + QString szMsg; + QString szName = pItem->name(); + + if(!*pbYesToAll) + { + saveLastEditedItem(); + if(pItem->isClass()) + { + KviQString::sprintf(szMsg,__tr2qs_ctx("Do you really want to remove the class \"%Q\" ?","editor"),&szName); + } else if(pItem->isNamespace()) + { + KviQString::sprintf(szMsg,__tr2qs_ctx("Do you really want to remove the namespace \"%Q\" ?","editor"),&szName); + szMsg += "
"; + szMsg += __tr2qs_ctx("Please note that all the children classes/functions will be deleted too.","editor"); + } else if(pItem->isMethod()) + { + KviQString::sprintf(szMsg,__tr2qs_ctx("Do you really want to remove the function \"%Q\" ?","editor"),&szName); + } + + g_pClassEditorModule->lock(); + int iRet = QMessageBox::question(this,__tr2qs_ctx("Remove item","editor"),szMsg,__tr2qs_ctx("Yes","editor"),__tr2qs_ctx("Yes to All","editor"),__tr2qs_ctx("No","editor")); + g_pClassEditorModule->unlock(); + switch(iRet) + { + case 0: + // nothing + break; + case 1: + *pbYesToAll = true; + break; + default: + return false; + break; + } + } + + if(pItem == m_pLastEditedItem) + m_pLastEditedItem = 0; + if(pItem == m_pLastClickedItem) + m_pLastClickedItem = 0; + if(pItem->childCount()) + removeItemChildren(pItem,lRemovedItems); + if(pItem->isClass()) + { + m_pClasses->removeRef(pItem); + KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(buildFullClassName(pItem)); + qDebug("rimuovo class %s %p",buildFullClassName(pItem).toUtf8().data(), pClass); + if(pClass) + KviKvsKernel::instance()->objectController()->deleteClass(pClass); + else + { + QString szFileName = buildFullClassName(pItem); + szFileName.replace("::","--"); + szFileName.append(KVI_FILEEXTENSION_SCRIPT); + QString szPath; + g_pApp->getLocalKvircDirectory(szPath,KviApplication::Classes); + QDir d(szPath); + if(d.exists(szFileName)) + { + qDebug("rimuovo dal disco il file %s",szFileName.toUtf8().data()); + d.remove(szFileName); + } + } + } + if(pItem->isMethod()) + { + updateClassHierarchy((ClassEditorTreeWidgetItem *)pItem->parent()); + } + lRemovedItems.append(pItem); + delete pItem; + return true; +} + +void ClassEditorWidget::updateClassHierarchy(ClassEditorTreeWidgetItem * pClass) +{ + pClass->setClassNotBuilt(true); + KviPointerList lInheritedClasses; + lInheritedClasses.setAutoDelete(false); + searchInheritedClasses(pClass->name(),lInheritedClasses); + for(unsigned int u=0; u < lInheritedClasses.count(); u++) + { + lInheritedClasses.at(u)->setClassNotBuilt(true); + lInheritedClasses.at(u)->setInheritsClass(pClass->name()); + lInheritedClasses.at(u)->setExpanded(true); + } +} + +void ClassEditorWidget::removeSelectedItems() +{ + KviPointerList lRemovedItems; + lRemovedItems.setAutoDelete(false); + QList list = m_pTreeWidget->selectedItems(); + bool bYesToAll = false; + for(int i=0; i < list.count(); i++) + { + if(lRemovedItems.findRef((ClassEditorTreeWidgetItem *) list.at(i)) != -1) + continue; + if(!removeItem((ClassEditorTreeWidgetItem *) list.at(i),lRemovedItems,&bYesToAll)) + return; + } +} + +bool ClassEditorWidget::askForClassName(QString & szClassName, QString & szInheritsClassName, bool bEdit) +{ + KviClassEditorDialog * pDialog = new KviClassEditorDialog(this,"classdialog",m_pClasses,szClassName,szInheritsClassName,bEdit); + szClassName = ""; + g_pClassEditorModule->lock(); + bool bOk = pDialog->exec(); + g_pClassEditorModule->unlock(); + if(bOk) + { + szClassName = pDialog->className(); + szInheritsClassName = pDialog->inheritsClassName(); + delete pDialog; + return true; + } + delete pDialog; + return false; +} + +bool ClassEditorWidget::askForFunction(QString & szFunctionName, QString & szReminder, bool * bInternal, const QString & szClassName, bool bRenameMode) +{ + KviClassEditorFunctionDialog * pDialog = new KviClassEditorFunctionDialog(this,"function",szClassName,szFunctionName,szReminder,*bInternal, bRenameMode); + szFunctionName = ""; + g_pClassEditorModule->lock(); + bool bOk = pDialog->exec(); + g_pClassEditorModule->unlock(); + if(bOk) + { + szFunctionName = pDialog->functionName(); + szReminder = pDialog->reminder(); + *bInternal = pDialog->isInternalFunction(); + delete pDialog; + return true; + } + delete pDialog; + return false; +} + +bool ClassEditorWidget::askForNamespaceName(const QString & szAction, const QString & szText, const QString & szInitialText, QString & szNewName) +{ + bool bOk = false; + while(szNewName.isEmpty()) + { + g_pClassEditorModule->lock(); + szNewName = QInputDialog::getText(this, + szAction, + szText, + QLineEdit::Normal, + szInitialText, + &bOk); + g_pClassEditorModule->unlock(); + if(!bOk) + return false; + if(szNewName.isEmpty()) + { + g_pClassEditorModule->lock(); + QMessageBox::warning(this, + __tr2qs_ctx("Missing Namespace Name","editor"), + __tr2qs_ctx("You must specify a valid name for the namespace","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + g_pClassEditorModule->unlock(); + continue; + } + + // we allow only [\w:]+ + QRegExp re("[\\w:]+"); + if(!re.exactMatch(szNewName)) + { + g_pClassEditorModule->lock(); + QMessageBox::information(this, + __tr2qs_ctx("Bad Namespace Name","editor"), + __tr2qs_ctx("Namespace names can contain only letters, digits, underscores and '::' namespace separators","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + g_pClassEditorModule->unlock(); + szNewName = ""; + continue; + } + // make sure that we have only doubled "::" and not ":" or ":::..." + QString szTmp = szNewName; + szTmp.replace("::","@"); // @ is not allowed by the rule above + if(szTmp.indexOf(":",Qt::CaseInsensitive) != -1) + { + g_pClassEditorModule->lock(); + QMessageBox::information(this, + __tr2qs_ctx("Bad Namespace Name","editor"), + __tr2qs_ctx("Stray ':' character in namespace name: did you mean ...:: ?","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + g_pClassEditorModule->unlock(); + szNewName = ""; + continue; + } + if(szTmp.indexOf("@@",Qt::CaseInsensitive) != -1) + { + g_pClassEditorModule->lock(); + QMessageBox::information(this, + __tr2qs_ctx("Bad Namespace Name","editor"), + __tr2qs_ctx("Found an empty namespace in namespace name","editor"), + __tr2qs_ctx("Ok, Let me try again...","editor")); + g_pClassEditorModule->unlock(); + szNewName = ""; + continue; + } + } + return true; +} + +void ClassEditorWidget::openParentItems(QTreeWidgetItem * pItem) +{ + if(pItem->parent()) + { + pItem->parent()->setExpanded(true); + openParentItems(pItem->parent()); + } +} + +void ClassEditorWidget::activateItem(QTreeWidgetItem * pItem) +{ + if(!pItem) + return; + openParentItems(pItem); + m_pTreeWidget->setCurrentItem(pItem); +} + +void ClassEditorWidget::newClass() +{ + QString szClassName; + QString szinheritsClassName; + askForClassName(szClassName,szinheritsClassName,false); + if(szClassName.isEmpty()) + return; + ClassEditorTreeWidgetItem * pItem = newItem(szClassName,ClassEditorTreeWidgetItem::Class); + + KviQString::escapeKvs(&szClassName, KviQString::EscapeSpace); + KviQString::escapeKvs(&szinheritsClassName, KviQString::EscapeSpace); + + QString szClass = "class("; + szClass += szClassName + "," + szinheritsClassName; + szClass += "){}\n"; + pItem->setInheritsClass(szinheritsClassName); + activateItem(pItem); + m_pClasses->insert(szClassName,pItem); + KviKvsScript::run(szClass,g_pActiveWindow); +} + +void ClassEditorWidget::newNamespace() +{ + QString szName; + if(!askForNamespaceName(__tr2qs_ctx("Add Namespace","editor"),__tr2qs_ctx("Please enter the name for the new namespace","editor"),"mynamespace",szName)) + return; + if(szName.isEmpty()) + return; + ClassEditorTreeWidgetItem * pItem = newItem(szName,ClassEditorTreeWidgetItem::Namespace); + activateItem(pItem); +} + +void ClassEditorWidget::newMemberFunction() +{ + QString szFunctionName; + QString szClassName; + QString szReminder; + + if(m_pLastClickedItem->isMethod()) + m_pLastClickedItem = (ClassEditorTreeWidgetItem*)m_pLastClickedItem->parent(); + szClassName = buildFullClassName(m_pLastClickedItem); + bool bInternal = false; + if(!askForFunction(szFunctionName, szReminder,&bInternal,szClassName,false)) + return; + if(szFunctionName.isEmpty()) + return; + + ClassEditorTreeWidgetItem * pItem = newItem(szFunctionName,ClassEditorTreeWidgetItem::Method); + pItem->setInternalFunction(bInternal); + if(!szReminder.isEmpty()) + pItem->setReminder(szReminder); + activateItem(pItem); + ((ClassEditorTreeWidgetItem*)pItem->parent())->setClassNotBuilt(true); +} + +ClassEditorTreeWidgetItem * ClassEditorWidget::newItem(QString & szName, ClassEditorTreeWidgetItem::Type eType) +{ + if(m_pLastClickedItem) + buildFullItemPath(m_pLastClickedItem,szName); + + QString szTmp; + if(findItem(szName)) + szName.append("1"); + + int iIdx = 2; + while(findItem(szName)) + { + szTmp.setNum(iIdx); + szName.chop(szTmp.length()); + szName.append(szTmp); + iIdx++; + } + ClassEditorTreeWidgetItem * pItem; + pItem = createFullItem(szName); + pItem->setType(eType); + return pItem; +} + +void ClassEditorWidget::build() +{ + saveLastEditedItem(); + KviPointerHashTableIterator it (*m_pClasses); + KviPointerList linkedClasses; + linkedClasses.setAutoDelete(false); + KviPointerList skipClasses; + skipClasses.setAutoDelete(false); + bool bErrorWhilecompiling = false; + while(it.current()) + { + ClassEditorTreeWidgetItem * pClass = it.current(); + if(skipClasses.findRef(it.current()) != -1) + { + ++it; + continue; + } + if(pClass->classNotBuilt()) + { + //qDebug("compiling %s",pClass->name().toUtf8().data()); + ClassEditorTreeWidgetItem * pParentClass = m_pClasses->find(pClass->inheritsClass()); + + linkedClasses.append(pClass); + //if (!pParentClass) qDebug("no parent class"); + while(pParentClass) + { + if(pParentClass->classNotBuilt()) + linkedClasses.append(pParentClass); + pParentClass = m_pClasses->find(pParentClass->inheritsClass()); + } + for(int i = linkedClasses.count()-1; i >= 0; i--) + { + QString szFullClassName = buildFullClassName(linkedClasses.at(i)); + KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(szFullClassName); + if(pClass) + KviKvsKernel::instance()->objectController()->deleteClass(pClass); + QString szClass; + exportClassBuffer(szClass, linkedClasses.at(i)); + KviKvsScript::run(szClass,g_pActiveWindow); + pClass = KviKvsKernel::instance()->objectController()->lookupClass(szFullClassName); + if(!pClass) + { + bErrorWhilecompiling = true; + QString szError = __tr2qs_ctx("Unable to compile class: ","editor"); + szError += szFullClassName + "\n"; + KviPointerList lInheritedClasses; + lInheritedClasses.setAutoDelete(false); + searchInheritedClasses(szFullClassName,lInheritedClasses); + if(lInheritedClasses.count()) + { + szError += __tr2qs_ctx("These inherited classes will be not compiled too:","editor"); + szError += "\n"; + for(unsigned int u=0; u < lInheritedClasses.count(); u++) + { + szError += buildFullClassName(lInheritedClasses.at(u)) + "\n"; + lInheritedClasses.at(u)->setClassNotBuilt(true); + skipClasses.append(lInheritedClasses.at(u)); + } + } + QMessageBox::critical(this,__tr2qs_ctx("Compilation error - KVIrc","editor"),szError, + QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton); + break; + } + //else qDebug("class compiled %s :\n",szClass.toUtf8().data()); + linkedClasses.at(i)->setClassNotBuilt(false); + m_pEditor->setModified(false); + } + } + ++it; + } + if(bErrorWhilecompiling) + saveNotBuiltClasses(); + else { + QString szFileName = "libkviclasseditortmp.kvc"; + QString szBuffer; + g_pApp->getLocalKvircDirectory(szBuffer,KviApplication::ConfigPlugins,szFileName); + KviConfigurationFile cfg(szBuffer,KviConfigurationFile::Write); + cfg.clear(); + cfg.sync(); + } + KviKvsKernel::instance()->objectController()->flushUserClasses(); +} + +void ClassEditorWidget::loadNotBuiltClasses() +{ + QString szFileName = "libkviclasseditortmp.kvc"; + QString szBuffer; + g_pApp->getLocalKvircDirectory(szBuffer,KviApplication::ConfigPlugins,szFileName); + KviConfigurationFile cfg(szBuffer,KviConfigurationFile::Read); + KviConfigurationFileIterator it(*(cfg.dict())); + + KviPointerList l; + l.setAutoDelete(true); + + while(it.current()) + { + l.append(new QString(it.currentKey())); + ++it; + } + + for(QString * pszTmp = l.first(); pszTmp; pszTmp = l.next()) + { + cfg.setGroup(*pszTmp); + ClassEditorTreeWidgetItem * pClassItem = createFullItem(*pszTmp); + m_pClasses->insert(*pszTmp,pClassItem); + pClassItem->setClassNotBuilt(true); + KviConfigurationFileGroup * pDict = cfg.dict()->find(*pszTmp); + if(pDict) + { + KviConfigurationFileGroupIterator it(*pDict); + KviPointerList names; + names.setAutoDelete(true); + while(it.current()) + { + names.append(new QString(it.currentKey())); + ++it; + } + for(QString * pszTmp = names.first(); pszTmp; pszTmp = names.next()) + { + + if(KviQString::equalCI(*pszTmp,"@Inherits")) + { + pClassItem->setInheritsClass(cfg.readEntry(*pszTmp,"")); + continue; + } + if((*pszTmp).left(9) == "@Reminder") + continue; + QString szCode = cfg.readEntry(*pszTmp,""); + ClassEditorTreeWidgetItem * pFunctionItem = findFunction(*pszTmp, pClassItem); + if(!pFunctionItem) + pFunctionItem = new ClassEditorTreeWidgetItem(pClassItem,ClassEditorTreeWidgetItem::Method,*pszTmp); + pFunctionItem->setBuffer(szCode); + QString szEntry = "@Reminder|" + (*pszTmp); + QString szReminder = cfg.readEntry(szEntry,""); + pFunctionItem->setReminder(szReminder); + } + } + } +} + +void ClassEditorWidget::saveNotBuiltClasses() +{ + saveLastEditedItem(); + KviPointerHashTableIterator it (*m_pClasses); + QString szFileName = "libkviclasseditortmp.kvc"; + QString szBuffer; + g_pApp->getLocalKvircDirectory(szBuffer,KviApplication::ConfigPlugins,szFileName); + KviConfigurationFile cfg(szBuffer,KviConfigurationFile::Write); + cfg.clear(); + + while(it.current()) + { + if(it.current()->classNotBuilt()) + { + KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(it.currentKey()); + if(pClass) + KviKvsKernel::instance()->objectController()->deleteClass(pClass); + + cfg.setGroup(it.currentKey()); + cfg.writeEntry("@Inherits",it.current()->inheritsClass()); + QString szReminderEntry; + for(int i=0; i < it.current()->childCount(); i++) + { + if(!((ClassEditorTreeWidgetItem *)it.current()->child(i))->reminder().isEmpty()) + { + szReminderEntry="@Reminder|"+((ClassEditorTreeWidgetItem *)it.current()->child(i))->name(); + cfg.writeEntry(szReminderEntry,((ClassEditorTreeWidgetItem *)it.current()->child(i))->reminder()); + } + cfg.writeEntry(((ClassEditorTreeWidgetItem *)it.current()->child(i))->name(),((ClassEditorTreeWidgetItem *)it.current()->child(i))->buffer()); + } + } + ++it; + } + cfg.sync(); +} + +void ClassEditorWidget::searchInheritedClasses(const QString szClass, KviPointerList & lInheritedClasses) +{ + KviPointerHashTableIterator it (*m_pClasses); + while(it.current()) + { + if(KviQString::equalCI(szClass,it.current()->inheritsClass())) + lInheritedClasses.append(it.current()); + ++it; + } +} + +ClassEditorWindow::ClassEditorWindow(KviMainWindow * pFrm) +: KviWindow(KVI_WINDOW_TYPE_SCRIPTEDITOR,pFrm,"classeditor",0) +{ + g_pClassEditorWindow = this; + + setFixedCaption(__tr2qs_ctx("Class Editor","editor")); + + QGridLayout * pLayout = new QGridLayout(); + + m_pEditor = new ClassEditorWidget(this); + pLayout->addWidget(m_pEditor,0,0,1,4); + + QPushButton * pBtn = new QPushButton(__tr2qs_ctx("&Build","editor"),this); + pBtn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT))); + pLayout->addWidget(pBtn,1,1); + connect(pBtn,SIGNAL(clicked()),this,SLOT(buildClicked())); + + pBtn = new QPushButton(__tr2qs_ctx("&Save","editor"),this); + pBtn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT))); + pLayout->addWidget(pBtn,1,2); + connect(pBtn,SIGNAL(clicked()),this,SLOT(saveClicked())); + + pBtn = new QPushButton(__tr2qs_ctx("Close","editor"),this); + pBtn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD))); + pLayout->addWidget(pBtn,1,3); + connect(pBtn,SIGNAL(clicked()),this,SLOT(cancelClicked())); + + pLayout->setRowStretch(0,1); + pLayout->setColumnStretch(0,1); + setLayout(pLayout); +} + +ClassEditorWindow::~ClassEditorWindow() +{ + g_pClassEditorWindow = 0; +} + +void ClassEditorWindow::buildClicked() +{ + m_pEditor->build(); +} + +void ClassEditorWindow::saveClicked() +{ + m_pEditor->saveNotBuiltClasses(); +} + +void ClassEditorWindow::cancelClicked() +{ + close(); +} + +QPixmap * ClassEditorWindow::myIconPtr() +{ + return g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASSEDITOR); +} + +void ClassEditorWindow::configGroupName(QString &szName) +{ + szName = "classeditor"; +} + +void ClassEditorWindow::saveProperties(KviConfigurationFile * pCfg) +{ + m_pEditor->saveProperties(pCfg); +} + +void ClassEditorWindow::loadProperties(KviConfigurationFile * pCfg) +{ + m_pEditor->loadProperties(pCfg); +} + +KviClassEditorDialog::KviClassEditorDialog(QWidget * pParent, const QString & szName, KviPointerHashTable * pClasses, const QString & szClassName, const QString & szInheritsClassName, bool bRenameMode) +: QDialog(pParent) +{ + setObjectName(szName); + + QGridLayout * pLayout = new QGridLayout(this); + + KviTalHBox * pHBox = new KviTalHBox(this); + pHBox->setSpacing(0); + pHBox->setMargin(0); + pLayout->addWidget(pHBox,0,0); + + QLabel * pLabel = new QLabel(pHBox); + pLabel->setObjectName("classnamelabel"); + pLabel->setText(__tr2qs_ctx("Please enter the name for the class:","editor")); + + m_pClassNameLineEdit = new QLineEdit(pHBox); + m_pClassNameLineEdit->setObjectName("classnameineedit"); + m_pClassNameLineEdit->setText(szClassName); + pLabel->setBuddy(m_pClassNameLineEdit); + QRegExp re; + if(!bRenameMode) + { + // we allow only [\w:]+ class name + re.setPattern("[\\w]+"); + m_pClassNameLineEdit->setToolTip(__tr2qs_ctx("Class names can contain only letters, digits and underscores","editor")); + } else { + // in editor mode we allow [\w:]+ and namespace separator + re.setPattern("[\\w]+(::[\\w]+)+"); + m_pClassNameLineEdit->setToolTip(__tr2qs_ctx("In rename mode class names can contain only letters, digits and underscores and namespaces :: separator","editor")); + } + QRegExpValidator * pValidator = new QRegExpValidator(re,this); + m_pClassNameLineEdit->setValidator(pValidator); + m_pClassNameLineEdit->setObjectName("functionameineedit"); + + pHBox = new KviTalHBox(this); + pHBox->setSpacing(0); + pHBox->setMargin(0); + pLayout->addWidget(pHBox,1,0); + + pLabel = new QLabel(pHBox); + pLabel->setObjectName("Inheritsclasslabel"); + pLabel->setText(__tr2qs_ctx("Inherits Class:","editor")); + + m_pInheritsClassComboBox = new QComboBox(pHBox); + pLabel->setBuddy(m_pInheritsClassComboBox); + + KviPointerHashTableIterator pClassesIt(*pClasses); + + QStringList szClasses; + while(pClassesIt.current()) + { + if(!KviQString::equalCI(pClassesIt.currentKey(),szClassName)) + szClasses.append(pClassesIt.currentKey()); + ++pClassesIt; + } + KviPointerHashTableIterator pBuiltinClasses(*KviKvsKernel::instance()->objectController()->classDict()); + while(pBuiltinClasses.current()) + { + if(pBuiltinClasses.current()->isBuiltin()) + szClasses.append(pBuiltinClasses.currentKey()); + ++pBuiltinClasses; + } + + int iCurrentIdx; + szClasses.sort(); + for(int i=0; i < szClasses.count(); i++) + m_pInheritsClassComboBox->addItem(szClasses.at(i)); + if(szInheritsClassName.isEmpty()) + iCurrentIdx = m_pInheritsClassComboBox->findText("object"); + else { + iCurrentIdx = m_pInheritsClassComboBox->findText(szInheritsClassName); + if(iCurrentIdx == -1) + iCurrentIdx = m_pInheritsClassComboBox->findText("object"); + } + m_pInheritsClassComboBox->setCurrentIndex(iCurrentIdx); + m_pClassNameLineEdit->setFocus(); + connect(m_pClassNameLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged(const QString &))); + + pHBox = new KviTalHBox(this); + pHBox->setSpacing(0); + pHBox->setMargin(0); + pLayout->addWidget(pHBox,2,0); + + m_pNewClassButton = new QPushButton(pHBox); + m_pNewClassButton->setObjectName("newclassbutton"); + if(bRenameMode) + m_pNewClassButton->setText(__tr2qs_ctx("&Rename Class","editor")); + else { + m_pNewClassButton->setText(__tr2qs_ctx("&Create Class","editor")); + m_pNewClassButton->setEnabled(false); + } + connect(m_pNewClassButton, SIGNAL(clicked()), this, SLOT(accept())); + + QPushButton * pCancelButton = new QPushButton(pHBox); + pCancelButton->setObjectName("cancelButton"); + pCancelButton->setText(__tr2qs_ctx("&Cancel","editor")); + connect(pCancelButton, SIGNAL(clicked()), this, SLOT(reject())); + + setLayout(pLayout); +} + +KviClassEditorDialog::~KviClassEditorDialog() +{ +} + +void KviClassEditorDialog::textChanged(const QString & szText) +{ + m_pNewClassButton->setEnabled(!szText.isEmpty()); +} + +KviClassEditorFunctionDialog::KviClassEditorFunctionDialog(QWidget * pParent, const QString & szName, const QString & szClassName, const QString & szFunctionName, const QString & szReminder, bool bIsInternal, bool bRenameMode) +: QDialog(pParent) +{ + setObjectName(szName); + + QGridLayout * pLayout = new QGridLayout(this); + + KviTalHBox * pHBox = new KviTalHBox(this); + pHBox->setSpacing(0); + pHBox->setMargin(0); + pLayout->addWidget(pHBox,0,0); + + QLabel * pLabel = new QLabel(pHBox); + pLabel->setObjectName("classnamelabel"); + pLabel->setText("Class: "+szClassName+""); + + pHBox = new KviTalHBox(this); + pHBox->setSpacing(0); + pHBox->setMargin(0); + pLayout->addWidget(pHBox,1,0); + + pLabel = new QLabel(pHBox); + pLabel->setObjectName("functionnamelabel"); + pLabel->setText(__tr2qs_ctx("Please enter the name for the member function:","editor")); + + m_pFunctionNameLineEdit = new QLineEdit(pHBox); + + // we allow only [\w:]+ function name + QRegExp re("[\\w]+"); + QRegExpValidator * pValidator = new QRegExpValidator(re,this); + m_pFunctionNameLineEdit->setValidator(pValidator); + m_pFunctionNameLineEdit->setObjectName("functionameineedit"); + m_pFunctionNameLineEdit->setToolTip(__tr2qs_ctx("Function names can contain only letters, digits and underscores","editor")); + m_pFunctionNameLineEdit->setText(szFunctionName); + pLabel->setBuddy(m_pFunctionNameLineEdit); + + pHBox = new KviTalHBox(this); + pHBox->setSpacing(0); + pHBox->setMargin(0); + pLayout->addWidget(pHBox,2,0); + + pLabel = new QLabel(pHBox); + pLabel->setObjectName("reminderlabel"); + pLabel->setWordWrap(1); + pLabel->setText(__tr2qs_ctx("Please enter the optional reminder string for the member function:","editor")); + + m_pReminderLineEdit = new QLineEdit(pHBox); + m_pReminderLineEdit->setText(szReminder); + pLabel->setBuddy(m_pReminderLineEdit); + + pHBox = new KviTalHBox(this); + pHBox->setSpacing(0); + pHBox->setMargin(0); + pLayout->addWidget(pHBox,3,0); + + pLabel = new QLabel(pHBox); + pLabel->setObjectName("functionnamelabel"); + pLabel->setText(__tr2qs_ctx("Set as Internal Function: ","editor")); + + m_pInternalCheckBox = new QCheckBox(pHBox); + m_pInternalCheckBox->setChecked(bIsInternal); + m_pFunctionNameLineEdit->setFocus(); + pLabel->setBuddy(m_pInternalCheckBox); + connect(m_pFunctionNameLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged(const QString &))); + + pHBox->setAlignment(m_pInternalCheckBox,Qt::AlignLeft); + pHBox->setStretchFactor(m_pInternalCheckBox,70); + pHBox->setStretchFactor(pLabel,30); + + pHBox = new KviTalHBox(this); + pHBox->setSpacing(0); + pHBox->setMargin(0); + pLayout->addWidget(pHBox,4,0); + + m_pNewFunctionButton = new QPushButton(pHBox); + m_pNewFunctionButton->setObjectName("newfunctionbutton"); + if(!bRenameMode) + m_pNewFunctionButton->setText(__tr2qs_ctx("&Add","editor")); + else + m_pNewFunctionButton->setText(__tr2qs_ctx("&Rename","editor")); + + if(szFunctionName.isEmpty()) + m_pNewFunctionButton->setEnabled(false); + connect(m_pNewFunctionButton, SIGNAL(clicked()), this, SLOT(accept())); + + QPushButton * pCancelButton = new QPushButton(pHBox); + pCancelButton->setObjectName("cancelButton"); + pCancelButton->setText(__tr2qs_ctx("&Cancel","editor")); + connect(pCancelButton, SIGNAL(clicked()), this, SLOT(reject())); + + setLayout(pLayout); +} + +KviClassEditorFunctionDialog::~KviClassEditorFunctionDialog() +{ +} + +void KviClassEditorFunctionDialog::textChanged(const QString & szText) +{ + m_pNewFunctionButton->setEnabled(!szText.isEmpty()); +} diff --git a/src/modules/classeditor/ClassEditorWindow.h b/src/modules/classeditor/ClassEditorWindow.h new file mode 100644 index 000000000..f13956c91 --- /dev/null +++ b/src/modules/classeditor/ClassEditorWindow.h @@ -0,0 +1,639 @@ +#ifndef _CLASSEDITOR_H_ +#define _CLASSEDITOR_H_ +//============================================================================= +// +// File : ClassEditorWindow.h +// Creation date : Mon Feb 15 2010 14:35:55 CEST by Carbone Alessandro +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2010 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the linkss of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +/** +* \file ClassEditorWindow.h +* \author Alessandro Carbone +* \brief Class Editor window +*/ + +#include "KviWindow.h" +#include "KviCString.h" +#include "KviPointerList.h" +#include "KviTalPopupMenu.h" +#include "KviHeapObject.h" +#include "KviKvsObjectClass.h" + +#include +#include +#include +#include +#include +#include + +class QLineEdit; +class QStringList; +class QPushButton; +class QCheckBox; +class QLabel; +class QSplitter; +class KviScriptEditor; + +/** +* \class ClassEditorTreeWidget +* \brief Describes the tree widget hierarchy +*/ +class ClassEditorTreeWidget : public QTreeWidget +{ + Q_OBJECT +public: + /** + * \brief Construct the tree widget + * \param pParent The parent widget + * \return ClassEditorTreeWidget + */ + ClassEditorTreeWidget(QWidget * pParent); + + /** + * \brief Destroys the tree widget + */ + ~ClassEditorTreeWidget(); +protected: + virtual void mousePressEvent(QMouseEvent * e); +signals: + /** + * \brief Emitted when we press the mouse right button + * \param pItem The item clicked + * \param pos The position of the cursor + * \return void + */ + void rightButtonPressed(QTreeWidgetItem * pItem, QPoint pos); +}; + +/** +* \class ClassEditorTreeWidgetItem +* \brief Describes an item inside the class editor tree widget +*/ +class ClassEditorTreeWidgetItem : public QTreeWidgetItem, public KviHeapObject +{ +public: + /** + * \enum Type + * \brief Contains the type of the class item + */ + enum Type + { + Class, /**< The item is a class */ + Namespace, /**< The item is a namespace */ + Method /**< The item is a member function */ + }; +public: + /** + * \brief Constructs the class editor tree widget item + * \param pTreeWidget The parent tree widget + * \param eType The type of the item + * \param szName The name of the item + * \return ClassEditorTreeWidgetItem + */ + ClassEditorTreeWidgetItem(QTreeWidget * pTreeWidget, Type eType, const QString & szName); + + /** + * \brief Constructs the class editor tree widget item + * \param pParentItem The parent tree widget item + * \param eType The type of the item + * \param szName The name of the item + * \return ClassEditorTreeWidgetItem + */ + ClassEditorTreeWidgetItem(ClassEditorTreeWidgetItem * pParentItem, Type eType, const QString & szName); + + /** + * \brief Destroys the class editor tree widget item + */ + ~ClassEditorTreeWidgetItem(){}; +protected: + Type m_eType; + QString m_szName; + QString m_szBuffer; + QString m_szInheritsClassName; + QString m_szReminder; + bool m_bClassModified; + bool m_bInternal; + int m_iPos; +public: + /** + * \brief Sets the class name on which the class inherits from + * \param szInheritsClassName The parent class name + * \return void + */ + void setInheritsClass(QString szInheritsClassName){ m_szInheritsClassName = szInheritsClassName; }; + + /** + * \brief Returns the class name of the classes we inherit from + * \return QString + */ + QString inheritsClass(){ return m_szInheritsClassName; }; + + /** + * \brief Returns the name of the item + * \return const QString & + */ + const QString & name(){ return m_szName; }; + + /** + * \brief Sets the name of the item + * \param szName The name of the item :P + * \return void + */ + void setName(const QString & szName); + + /** + * \brief Sets the list of parameters the function accept + * \param szRem The parameters' list + * \return void + */ + void setReminder(const QString & szRem){ m_szReminder = szRem; }; + + /** + * \brief Returns the parameters list + * \return QString + */ + QString reminder(){ return m_szReminder; }; + + /** + * \brief Sets the state of the class as non-built + * \param bModified Whether the class is modified + * \return void + */ + void setClassNotBuilt(bool bModified); + + /** + * \brief Returns true if we class is not built yet, false otherwise + * \return bool + */ + bool classNotBuilt(){ return m_bClassModified; }; + + /** + * \brief Sets the function as internal + * \param bInternal Whether the function is internal or not + * \return void + */ + void setInternalFunction(bool bInternal){ m_bInternal = bInternal; }; + + /** + * \brief Returns true if the function is set as internal, false otherwise + * \return bool + */ + bool isInternalFunction(){ return m_bInternal; }; + + /** + * \brief Returns the type of the item + * \return Type + */ + Type type(){ return m_eType; }; + + /** + * \brief Sets the type of the item + * \param eType The type! + * \return void + */ + void setType(Type eType); + + /** + * \brief Returns true if the item is a class, false otherwise + * \return bool + */ + bool isClass(){ return m_eType == Class; }; + + /** + * \brief Returns true if the item is a namespace, false otherwise + * \return bool + */ + bool isNamespace(){ return m_eType == Namespace; }; + + /** + * \brief Returns true if the item is a member function, false otherwise + * \return bool + */ + bool isMethod(){ return m_eType == Method; }; + + /** + * \brief Saves the code of the item in a buffer + * \param szBuffer The buffer ;) + * \return void + */ + void setBuffer(const QString & szBuffer){ m_szBuffer = szBuffer; }; + + /** + * \brief Returns the buffer containing the code of the item + * \return const QString & + */ + const QString & buffer(){ return m_szBuffer; }; + + /** + * \brief Returns the cursor's position + * \return const int & + */ + const int & cursorPosition(){ return m_iPos; }; + + /** + * \brief Sets the cursor position + * \param iPos The position of the cursor + * \return void + */ + void setCursorPosition(const int & iPos){ m_iPos = iPos; }; +}; + +/** +* \class ClassEditorWidget +* \brief The Class Editor module +*/ +class ClassEditorWidget : public QWidget +{ + Q_OBJECT +public: + /** + * \brief Constructs the class editor object + * \param pParent The parent widget + * \return ClassEditorWidget + */ + ClassEditorWidget(QWidget * pParent); + + /** + * \brief Destroys the class editor object + */ + ~ClassEditorWidget(); +public: + KviScriptEditor * m_pEditor; + ClassEditorTreeWidget * m_pTreeWidget; + QLabel * m_pClassNameLabel; + QPushButton * m_pClassNameRenameButton; + QLabel * m_pFunctionNameLabel; + QPushButton * m_pFunctionNameRenameButton; + QLabel * m_pReminderLabel; + + ClassEditorTreeWidgetItem * m_pLastEditedItem; + ClassEditorTreeWidgetItem * m_pLastClickedItem; + KviTalPopupMenu * m_pContextPopup; + QSplitter * m_pSplitter; + QString m_szDir; + bool m_bSaving; +protected: + KviPointerHashTable * m_pClasses; +public: + /** + * \brief Called to save the window properties + * \param pCfg The configuration file + * \return void + */ + virtual void saveProperties(KviConfigurationFile * pCfg); + + /** + * \brief Called to load the window properties + * \param pCfg The configuration file + * \return void + */ + virtual void loadProperties(KviConfigurationFile * pCfg); + + /** + * \brief Builds the class! + * \return void + */ + void build(); + + /** + * \brief Saves non-built classes to a file + * \return void + */ + void saveNotBuiltClasses(); + + /** + * \brief Loads non-built classes to a file + * \return void + */ + void loadNotBuiltClasses(); + + /** + * \brief Searches a function + * \param szFunctionName The name of the function + * \param pClass The class in which the function is + * \return ClassEditorTreeWidgetItem * + */ + ClassEditorTreeWidgetItem * findFunction(const QString & szFunctionName, ClassEditorTreeWidgetItem * pClass); + + /** + * \brief Exports class to a file + * \param bSelectedOnly Whether to export only selected files + * \param bSingleFiles Whether to export to single files + * \return void + */ + void exportClasses(bool bSelectedOnly, bool bSingleFiles = false); + + /** + * \brief Exports the current selection to single files + * \param pList The list of file to export + * \return void + */ + void exportSelectionInSinglesFiles(KviPointerList * pList); + + /** + * \brief Removes the item from the tree + * \param pItem The item to remove + * \return void + */ + void cutItem(ClassEditorTreeWidgetItem * pItem); +protected: + //void recursiveSearchReplace(const QString &szSearch,ClassEditorTreeWidgetItem * it,bool bReplace=false,const QString &szReplace="n"); + + void exportClassBuffer(QString & szBuffer, ClassEditorTreeWidgetItem * pItem); + + void oneTimeSetup(); + void createFullClass(KviKvsObjectClass * pClass, ClassEditorTreeWidgetItem * pItem, const QString & szClassName); + + void saveLastEditedItem(); + void appendSelectedClassItems(KviPointerList * pList); + void appendSelectedClassItemsRecursive(KviPointerList * pList, QTreeWidgetItem * pStartFrom); + + void appendAllClassItems(KviPointerList * pList); + void appendAllClassItemsRecursive(KviPointerList * l,QTreeWidgetItem * pStartFrom); + + void openParentItems(QTreeWidgetItem * pItem); + void activateItem(QTreeWidgetItem * pItem); + bool hasSelectedItems(); + bool askForClassName(QString & szClassName, QString & szInheritsClassName, bool bEdit); + bool askForNamespaceName(const QString & szAction, const QString & szText, const QString & szInitialText, QString & szNameBuffer); + bool askForFunction(QString & szFunctionName, QString & szReminder, bool * pbInternal, const QString & szClassName, bool bRenameMode); + void searchInheritedClasses(const QString szClass, KviPointerList & lInheritsedClasses); + + /** + * \brief Returns true if the class exists, false otherwise + * \param szName The name of the class + * \return bool + */ + bool classExists(QString & szName); + + /** + * \brief Renames a class + * \param pClass The class to rename + * \return void + */ + void renameClass(ClassEditorTreeWidgetItem * pClass); + + /** + * \brief Renames a namespace + * \param pNamespace The namespace to rename + * \return void + */ + void renameNamespace(ClassEditorTreeWidgetItem * pNamespace); + + bool removeItem(ClassEditorTreeWidgetItem * pItem, KviPointerList & lRemovedItems, bool * pbYesToAll); + void updateClassHierarchy(ClassEditorTreeWidgetItem * pClass); + + void removeItemChildren(ClassEditorTreeWidgetItem * pItem, KviPointerList & lRemovedItems); + void buildFullItemPath(ClassEditorTreeWidgetItem * pItem, QString & szBuffer); + QString buildFullClassName(ClassEditorTreeWidgetItem * pItem); + ClassEditorTreeWidgetItem * createFullItem(const QString & szFullName); + ClassEditorTreeWidgetItem * createFullNamespace(const QString & szFullName); + + /** + * \brief Searches an item + * \param szName The name of the item to find + * \return ClassEditorTreeWidgetItem * + */ + ClassEditorTreeWidgetItem * findItem(const QString & szName); + + + + ClassEditorTreeWidgetItem * findTopLevelItem(const QString & szName); + ClassEditorTreeWidgetItem * createFullItemRecursive(QTreeWidgetItem * pCurrent, QStringList & lNameSpaces, int & iLevel, bool bCreateNameSpace = 0); +protected slots: + void currentItemChanged(QTreeWidgetItem * pItem, QTreeWidgetItem *); + void customContextMenuRequested(QPoint); + void newClass(); + void newNamespace(); + void newMemberFunction(); + void renameFunction(); + ClassEditorTreeWidgetItem * newItem(QString & szName, ClassEditorTreeWidgetItem::Type eType); + + void renameItem(); + + void exportAll(); + void exportSelectedSepFiles(); + void exportSelected(); + void slotFind(); + void slotFindWord(const QString &); + void searchReplace(const QString & szSearch, bool bReplace = false, const QString & szReplace = "n"); + + /** + * \brief Called when we collapse an item + * \param pItem The item to collapse + * \return void + */ + void slotCollapseItems(); + + /** + * \brief Called when we collapse an item recursively + * \param pItem The starting item to collapse + * \return void + */ + void recursiveCollapseItems(ClassEditorTreeWidgetItem * pItem); + + /** + * \brief Called when we want to remove all selected items + * \return void + */ + void removeSelectedItems(); + + /** + * \brief Called when we replace text everywhere + * \param szBefore The text before the replace + * \param szAfter The text after the replace + * \return void + */ + void slotReplaceAll(const QString & szBefore, const QString & szAfter); +}; + +/** +* \class ClassEditorWindow +* \brief This is the Class Editor window +*/ +class ClassEditorWindow : public KviWindow +{ + Q_OBJECT +public: + /** + * \brief Constructs the class editor window + * \param pFrm The parent frame + * \return ClassEditorWindow + */ + ClassEditorWindow(KviMainWindow * pFrm); + + /** + * \brief Destroys the class editor window + */ + ~ClassEditorWindow(); +protected: + ClassEditorWidget * m_pEditor; +protected: + /** + * \brief Returns the class editor small icon + * \return QPixmap * + */ + virtual QPixmap * myIconPtr(); + + /** + * \brief Sets the configuration group name as classeditor + * \param szName The name of the group + * \return void + */ + virtual void configGroupName(QString & szName); + + /** + * \brief Called to save the window properties + * \param pCfg The configuration file + * \return void + */ + virtual void saveProperties(KviConfigurationFile * pCfg); + + /** + * \brief Called to load the window properties + * \param pCfg The configuration file + * \return void + */ + virtual void loadProperties(KviConfigurationFile * pCfg); +protected slots: + /** + * \brief Called when we click the cancel button + * \return void + */ + void cancelClicked(); + + /** + * \brief Called when we want to build the class + * \return void + */ + void buildClicked(); + + /** + * \brief Called when we want to save the class + * \return void + */ + void saveClicked(); +}; + +/** +* \class KviClassEditorDialog +* \brief This class constructs the dialog to create a new class +*/ +class KviClassEditorDialog: public QDialog +{ + Q_OBJECT +public: + /** + * \brief Constructs the class dialog + * \param pParent The parent widget + * \param szName The name of the widget + * \param pClasses The container of all classes of our namespace + * \param szClassName The name of the class + * \param szInheritsClassName The name of the classes in which this inherits from + * \param bRenameMode Whether the dialog is in rename mode + * \return KviClassEditorDialog + */ + KviClassEditorDialog(QWidget * pParent, const QString & szName, KviPointerHashTable * pClasses, const QString & szClassName, const QString & szInheritsClassName, bool bRenameMode = false); + + /** + * \brief Destroys the class dialog + */ + ~KviClassEditorDialog(); +protected: + QPushButton * m_pNewClassButton; + QLineEdit * m_pClassNameLineEdit; + QComboBox * m_pInheritsClassComboBox; +public: + /** + * \brief Returns the class name + * \return QString + */ + QString className(){ return m_pClassNameLineEdit->text(); }; + + /** + * \brief Returns the class name of the parent classes + * \return QString + */ + QString inheritsClassName(){ return m_pInheritsClassComboBox->currentText(); }; +protected slots: + /** + * \brief Triggered when the name of the class change + * \return void + */ + void textChanged(const QString &); +}; + +/** +* \class KviClassEditorFunctionDialog +* \brief This class constructs the dialog to create a new member function +*/ +class KviClassEditorFunctionDialog: public QDialog +{ + Q_OBJECT +public: + /** + * \brief Constructs the function dialog + * \param pParent The parent widget + * \param szName The name of the widget + * \param szClassName The name of the class + * \param szFunctionName The name of the function + * \param szReminder The parameters of the function + * \param bIsInternal Whether the funtion is set as internal + * \param bRenameMode Whether the dialog is in rename mode + * \return KviClassEditorFunctionDialog + */ + KviClassEditorFunctionDialog(QWidget * pParent, const QString & szName, const QString & szClassName, const QString & szFunctionName, const QString & szReminder, bool bIsInternal, bool bRenameMode = false); + + /** + * \brief Destroys the function dialog + */ + ~KviClassEditorFunctionDialog(); +protected: + QPushButton * m_pNewFunctionButton; + QLineEdit * m_pFunctionNameLineEdit; + QLineEdit * m_pReminderLineEdit; + QCheckBox * m_pInternalCheckBox; +public: + /** + * \brief Returns the function name + * \return QString + */ + QString functionName(){ return m_pFunctionNameLineEdit->text(); }; + + /** + * \brief Returns the parameters of the function + * \return QString + */ + QString reminder(){ return m_pReminderLineEdit->text(); }; + + /** + * \brief Returns true if the function is set as internal, false otherwise + * \return bool + */ + bool isInternalFunction(){ return m_pInternalCheckBox->isChecked(); }; +protected slots: + /** + * \brief Triggered when the name of the function change + * \return void + */ + void textChanged(const QString &); +}; +#endif //_CLASSEDITOR_H_ diff --git a/src/modules/classeditor/classeditor.cpp b/src/modules/classeditor/classeditor.cpp deleted file mode 100644 index 4d4569b0c..000000000 --- a/src/modules/classeditor/classeditor.cpp +++ /dev/null @@ -1,2101 +0,0 @@ -//============================================================================= -// -// File : classeditor.cpp -// Creation date : Mon Feb 15 2010 14:35:55 CEST by Carbone Alessandro -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2010 Alessandro Carbone (elfonol at gmail dot com) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the linkss of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - - -#include "classeditor.h" - -#include "KviIconManager.h" -#include "KviOptions.h" -#include "KviLocale.h" -#include "KviImageDialog.h" -#include "KviConfigurationFile.h" -#include "KviFileDialog.h" -#include "KviFileUtils.h" -#include "KviScriptEditor.h" -#include "kvi_debug.h" -#include "KviApplication.h" -#include "KviMainWindow.h" -#include "KviQString.h" -#include "KviKvsKernel.h" -#include "KviKvsObjectClass.h" -#include "KviKvsObjectController.h" -#include "KviFileDialog.h" -#include "KviCommandFormatter.h" -#include "KviModule.h" -#include "KviTalVBox.h" -#include "kvi_fileextensions.h" -#include "KviModuleManager.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern KviClassEditorWindow * g_pClassEditorWindow; -extern KviModule * g_pClassEditorModule; - -KviClassEditorTreeWidget::KviClassEditorTreeWidget(QWidget * pParent) -: QTreeWidget(pParent) -{ - setColumnCount (1); - setHeaderLabel(__tr2qs_ctx("Class","editor")); - setSelectionMode(QAbstractItemView::ExtendedSelection); - setSortingEnabled(true); - setRootIsDecorated(true); - setAnimated(true); -} - -KviClassEditorTreeWidget::~KviClassEditorTreeWidget() -{ - //remove and delete all items - clear(); -} - -void KviClassEditorTreeWidget::mousePressEvent(QMouseEvent * e) -{ - if(e->button() == Qt::RightButton) - { - QTreeWidgetItem * pItem = itemAt(e->pos()); - if(pItem) - emit rightButtonPressed(pItem,QCursor::pos()); - } - QTreeWidget::mousePressEvent(e); -} - -KviClassEditorTreeWidgetItem::KviClassEditorTreeWidgetItem(QTreeWidget * pTreeWidget, Type eType, const QString & szName) -: QTreeWidgetItem(pTreeWidget), KviHeapObject(), m_eType(eType) -{ - setName(szName); - m_szInheritsClassName = ""; - m_iPos = 0; - m_bInternal = false; - m_bClassModified = false; - QPixmap * pIcon = 0; - - if(eType == KviClassEditorTreeWidgetItem::Namespace) - pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE); - else - pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASS); - - setIcon(0,QIcon(*pIcon)); -} - -KviClassEditorTreeWidgetItem::KviClassEditorTreeWidgetItem(KviClassEditorTreeWidgetItem * pParentItem, Type eType, const QString & szName) -: QTreeWidgetItem(pParentItem), m_eType(eType) -{ - setFlags(Qt::ItemIsEditable|Qt::ItemIsEnabled|Qt::ItemIsSelectable); - setName(szName); - m_szInheritsClassName = ""; - m_bInternal = false; - m_iPos = 0; - m_bClassModified = false; - QPixmap * pIcon = 0; - - if(eType == KviClassEditorTreeWidgetItem::Namespace) - pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE); - else if(eType == KviClassEditorTreeWidgetItem::Class) - pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASS); - else - pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_FUNCTION); - - setIcon(0,QIcon(*pIcon)); -} - -void KviClassEditorTreeWidgetItem::setClassNotBuilt(bool bModified) -{ - m_bClassModified = bModified; - QPixmap * pIcon = 0; - - if(bModified) - pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASSNOTBUILT); - else - pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASS); - - setIcon(0,QIcon(*pIcon)); -} - -void KviClassEditorTreeWidgetItem::setName(const QString & szName) -{ - m_szName = szName; - setText(0,m_szName); -} - -void KviClassEditorTreeWidgetItem::setType(Type eType) -{ - m_eType = eType; - QPixmap * pIcon = 0; - - if(eType == KviClassEditorTreeWidgetItem::Namespace) - pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE); - else if(eType == KviClassEditorTreeWidgetItem::Class) - pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASS); - else - pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_FUNCTION); - - setIcon(0,QIcon(*pIcon)); -} - -KviClassEditor::KviClassEditor(QWidget * pParent) -: QWidget(pParent) -{ - m_pClasses = new KviPointerHashTable(100,false); - m_pClasses->setAutoDelete(false); - m_pLastEditedItem = 0; - m_pLastClickedItem = 0; - m_szDir = QDir::homePath(); - - QGridLayout * pLayout = new QGridLayout(this); - - m_pSplitter = new QSplitter(Qt::Horizontal,this); - m_pSplitter->setChildrenCollapsible(false); - pLayout->addWidget(m_pSplitter,0,0); - - KviTalVBox * pVBox = new KviTalVBox(m_pSplitter); - pVBox->setSpacing(0); - pVBox->setMargin(0); - m_pTreeWidget = new KviClassEditorTreeWidget(pVBox); - - pVBox = new KviTalVBox(m_pSplitter); - - KviTalHBox * pHBox = new KviTalHBox(pVBox); - pHBox->setSpacing(0); - pHBox->setMargin(0); - m_pClassNameLabel = new QLabel(__tr2qs_ctx("No item selected","editor"),pHBox); - pHBox->setStretchFactor(m_pClassNameLabel,2); - m_pClassNameLabel->setWordWrap(true); - m_pClassNameRenameButton = new QPushButton(__tr2qs_ctx("Rename","editor"),pHBox); - m_pClassNameRenameButton->setToolTip(__tr2qs_ctx("Edit the class or namespace name","editor")); - m_pClassNameRenameButton->setEnabled(false); - connect(m_pClassNameRenameButton,SIGNAL(clicked()),this,SLOT(renameItem())); - - pHBox = new KviTalHBox(pVBox); - pHBox->setSpacing(0); - pHBox->setMargin(0); - - pHBox = new KviTalHBox(pVBox); - pHBox->setSpacing(0); - pHBox->setMargin(0); - m_pFunctionNameLabel = new QLabel(__tr2qs_ctx("No item selected","editor"),pHBox); - pHBox->setStretchFactor(m_pFunctionNameLabel,2); - m_pFunctionNameRenameButton = new QPushButton(__tr2qs_ctx("Rename","editor"),pHBox); - m_pFunctionNameRenameButton->setToolTip(__tr2qs_ctx("Edit the function member name","editor")); - m_pFunctionNameRenameButton->setEnabled(false); - connect(m_pFunctionNameRenameButton,SIGNAL(clicked()),this,SLOT(renameFunction())); - - m_pReminderLabel = new QLabel(__tr2qs_ctx("No item selected","editor"),pVBox); - m_pReminderLabel->hide(); - m_pReminderLabel->setWordWrap(true); - - m_pEditor = KviScriptEditor::createInstance(pVBox); - m_pEditor->setFocus(); - connect(m_pEditor,SIGNAL(find(const QString &)),this,SLOT(slotFindWord(const QString &))); - connect(m_pEditor,SIGNAL(replaceAll(const QString &,const QString &)),this,SLOT(slotReplaceAll(const QString &,const QString &))); - m_pContextPopup = new KviTalPopupMenu(this); - - oneTimeSetup(); - - currentItemChanged(0,0); -} - -KviClassEditor::~KviClassEditor() -{ - m_pClasses->clear(); - delete m_pClasses; -} - -void KviClassEditor::buildFullItemPath(KviClassEditorTreeWidgetItem * pItem, QString & szBuffer) -{ - if(!pItem) - return; - szBuffer.prepend(pItem->name() + "::"); - pItem = (KviClassEditorTreeWidgetItem *)pItem->parent(); - while(pItem) - { - QString szTmp = pItem->name(); - if(!szTmp.isEmpty()) - { - szBuffer.prepend("::"); - szBuffer.prepend(szTmp); - } - pItem = (KviClassEditorTreeWidgetItem *)pItem->parent(); - } -} - -QString KviClassEditor::buildFullClassName(KviClassEditorTreeWidgetItem * pItem) -{ - if(!pItem) - return QString(); - QString szName = pItem->name(); - KviClassEditorTreeWidgetItem * pNItem = (KviClassEditorTreeWidgetItem *)pItem->parent(); - while(pNItem) - { - QString szTmp = pNItem->name(); - if(!szTmp.isEmpty()) - { - szName.prepend("::"); - szName.prepend(szTmp); - } - pNItem = (KviClassEditorTreeWidgetItem *)pNItem->parent(); - } - return szName; -} - -KviClassEditorTreeWidgetItem * KviClassEditor::findTopLevelItem(const QString & szName) -{ - for(int i=0; i < m_pTreeWidget->topLevelItemCount(); i++) - { - if(KviQString::equalCI(m_pTreeWidget->topLevelItem(i)->text(0),szName)) - return (KviClassEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i); - } - return 0; -} - -KviClassEditorTreeWidgetItem * KviClassEditor::findItem(const QString & szFullName) -{ - bool bFound; - QStringList lNamespaces = szFullName.split("::"); - if(lNamespaces.count() == 0) - return 0; - KviClassEditorTreeWidgetItem * pItem = findTopLevelItem(lNamespaces.at(0)); - if(!pItem) - return 0; - - for(int i=1; i < lNamespaces.count(); i++) - { - bFound = false; - for(int j=0; j < pItem->childCount(); j++) - { - if (KviQString::equalCI(pItem->child(j)->text(0),lNamespaces.at(i))) - { - pItem=( KviClassEditorTreeWidgetItem *)pItem->child(j); - bFound = true; - break; - } - } - if(!bFound) - return 0; - } - return (KviClassEditorTreeWidgetItem *)pItem; -} - -KviClassEditorTreeWidgetItem * KviClassEditor::createFullItem(const QString & szFullName) -{ - bool bFound; - int i; - - QStringList lNamespaces = szFullName.split("::"); - if(lNamespaces.count() == 0) - return 0; - if(lNamespaces.count() == 1) - { - KviClassEditorTreeWidgetItem * pItem = findTopLevelItem(lNamespaces.at(0)); - if(pItem) - return pItem; - return new KviClassEditorTreeWidgetItem(m_pTreeWidget,KviClassEditorTreeWidgetItem::Class,lNamespaces.at(0)); - } - KviClassEditorTreeWidgetItem * pItem = findTopLevelItem(lNamespaces.at(0)); - if(!pItem) - pItem = new KviClassEditorTreeWidgetItem(m_pTreeWidget,KviClassEditorTreeWidgetItem::Namespace,lNamespaces.at(0)); - - for(i=1; i < lNamespaces.count()-1; i++) - { - bFound = false; - for(int j=0; j < pItem->childCount();j++) - { - if(KviQString::equalCI(pItem->child(j)->text(0),lNamespaces.at(i))) - { - pItem = (KviClassEditorTreeWidgetItem *)pItem->child(j); - bFound = true; - break; - } - } - if(!bFound) - pItem = new KviClassEditorTreeWidgetItem(pItem,KviClassEditorTreeWidgetItem::Namespace,lNamespaces.at(i)); - } - return new KviClassEditorTreeWidgetItem(pItem,KviClassEditorTreeWidgetItem::Class,lNamespaces.at(i)); -} - -KviClassEditorTreeWidgetItem * KviClassEditor::createFullNamespace(const QString & szFullName) -{ - bool bFound; - int i; - - QStringList lNamespaces = szFullName.split("::"); - if(lNamespaces.count() == 0) - return 0; - KviClassEditorTreeWidgetItem * pItem = findTopLevelItem(lNamespaces.at(0)); - if(!pItem) - pItem = new KviClassEditorTreeWidgetItem(m_pTreeWidget,KviClassEditorTreeWidgetItem::Namespace,lNamespaces.at(0)); - if(lNamespaces.count() == 1) - return pItem; - - for(i=1; i < lNamespaces.count(); i++) - { - bFound = false; - for(int j=0;jchildCount();j++) - { - if(KviQString::equalCI(pItem->child(j)->text(0),lNamespaces.at(i)) && (( KviClassEditorTreeWidgetItem *)pItem->child(j))->isNamespace()) - { - pItem = (KviClassEditorTreeWidgetItem *)pItem->child(j); - bFound = true; - break; - } - } - if(!bFound) - pItem = new KviClassEditorTreeWidgetItem(pItem,KviClassEditorTreeWidgetItem::Namespace,lNamespaces.at(i)); - } - return pItem; -} - -void KviClassEditor::oneTimeSetup() -{ - QStringList sl; - QString szClassName; - QString szPath; - g_pApp->getLocalKvircDirectory(szPath,KviApplication::Classes); - QDir d(szPath); - - QString szExtension = QString("*%1").arg(KVI_FILEEXTENSION_SCRIPT); // *.kvs - sl = d.entryList(QStringList(szExtension), QDir::Files | QDir::NoDotAndDotDot); - - g_pModuleManager->getModule("objects"); - KviPointerHashTableIterator it(*KviKvsKernel::instance()->objectController()->classDict()); - - KviKvsObjectClass * pClass = 0; - KviClassEditorTreeWidgetItem * pClassItem = 0; - while(KviKvsObjectClass * pClass = it.current()) - { - if(pClass->isBuiltin()) - m_pClasses->insert(it.currentKey(),0); - else - { - QString szTmp; - szTmp = it.currentKey(); - szTmp.replace("::","--"); - szTmp.append(".kvs"); - if(sl.indexOf(szTmp) == -1) - { - szClassName = it.currentKey(); - pClassItem = createFullItem(szClassName); - createFullClass(it.current(),pClassItem,szClassName); - } - } - ++it; - } - - for(int i=0; i < sl.count(); i++) - { - szClassName = sl.at(i); - szClassName.replace("--","::"); - szClassName.chop(4); - pClassItem = createFullItem(szClassName); - pClass = KviKvsKernel::instance()->objectController()->lookupClass(szClassName); - if(pClass) - createFullClass(pClass, pClassItem, szClassName); - } - loadNotBuiltClasses(); - connect(m_pTreeWidget,SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),this,SLOT(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *))); - m_pTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu); - connect(m_pTreeWidget,SIGNAL(customContextMenuRequested(const QPoint &)),this,SLOT(customContextMenuRequested(const QPoint &))); -} - -void KviClassEditor::createFullClass(KviKvsObjectClass * pClass, KviClassEditorTreeWidgetItem * pClassItem, const QString & szClassName) -{ - KviPointerHashTableIterator it(* pClass->getHandlers()); - QStringList szFunctionsList; - while(it.current()) - { - szFunctionsList.append(it.currentKey()); - ++it; - } - szFunctionsList.sort(); - KviClassEditorTreeWidgetItem *pFunctionItem; - m_pClasses->insert(szClassName,pClassItem); - KviKvsObjectClass * pParentClass = pClass->parentClass(); - pClassItem->setInheritsClass(pParentClass->name()); - for(int i=0;ilookupFunctionHandler(szFunctionsList.at(i)); - if (pClass->isScriptHandler(szFunctionsList.at(i)) && !pHandler->isClone()) - { - pFunctionItem=findFunction(szFunctionsList.at(i), pClassItem); - if(!pFunctionItem) pFunctionItem = new KviClassEditorTreeWidgetItem(pClassItem,KviClassEditorTreeWidgetItem::Method,szFunctionsList.at(i)); - pClass->getFunctionCode(szCode,*pHandler); - pFunctionItem->setBuffer(szCode); - pFunctionItem->setReminder(pClass->reminder(pHandler)); - if(pHandler->flags() & KviKvsObjectFunctionHandler::Internal) - pFunctionItem->setInternalFunction(true); - } - //++it; - } -} - - -/* -void KviClassEditor::classRefresh(const QString & szName) -{ - if(m_bSaving) - return; - KviClassEditorTreeWidgetItem * item; - KviKvsScript * class = KviKvsClassManager::instance()->classDict()->find(szName); - item = createFullItem(szName); - if(item!=m_pLastEditedItem) - { - item->setBuffer(class->code()); - return; - } - if( - QMessageBox::warning(0,__tr2qs_ctx("OverWrite Current Class","editor"), - __tr2qs_ctx("An external script has changed the class you are currently editing. Do you want to accept the external changes?","editor"), - QMessageBox::Yes,QMessageBox::No|QMessageBox::Default|QMessageBox::Escape) != QMessageBox::Yes - ) - return; - item->setBuffer(class->code()); - m_pEditor->setText(class->code()); -} -*/ - -bool KviClassEditor::hasSelectedItems() -{ - return m_pTreeWidget->selectedItems().count() ? 1 : 0; -} - -bool KviClassEditor::classExists(QString & szFullItemName) -{ - if(m_pClasses->find(szFullItemName)) - return true; - else - return false; -} - -void KviClassEditor::renameFunction() -{ - if(!m_pLastEditedItem) - return; - KviClassEditorTreeWidgetItem * pFunction = m_pLastEditedItem; - QString szClassName = buildFullClassName((KviClassEditorTreeWidgetItem *)pFunction->parent()); - QString szFunctionName = pFunction->name(); - QString szReminder = pFunction->reminder(); - QString szNewReminder = szReminder; - KviClassEditorTreeWidgetItem * pParentClass = (KviClassEditorTreeWidgetItem *) pFunction->parent(); - - QString szNewFunctionName = szFunctionName; - bool bInternal = pFunction->isInternalFunction(); - if(!askForFunction(szNewFunctionName,szNewReminder,&bInternal,szClassName,true)) - return; - if(KviQString::equalCS(szFunctionName,szNewFunctionName) && bInternal == pFunction->isInternalFunction()) - { - if(!KviQString::equalCS(szNewReminder,szReminder)) - { - pFunction->setReminder(szNewReminder); - KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(szClassName); - if(pClass) - { - KviKvsObjectFunctionHandler * pHandler = pClass->lookupFunctionHandler(szFunctionName); - if(pHandler) - { - pClass->setReminder(szNewReminder,pHandler); - QString szPath; - QString szFileName = szClassName.toLower(); - szFileName += ".kvs"; - szFileName.replace("::","--"); - g_pApp->getLocalKvircDirectory(szPath,KviApplication::Classes,szFileName); - pClass->save(szPath); - } - } - currentItemChanged(pFunction,pFunction); - } else { - g_pClassEditorModule->lock(); - QMessageBox::information(this, - __tr2qs_ctx("Function already exists","editor"), - __tr2qs_ctx("This name is already in use. Please choose another one.","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - g_pClassEditorModule->unlock(); - return; - } - } - - pFunction->setName(szNewFunctionName); - pFunction->setReminder(szNewReminder); - currentItemChanged(pFunction,pFunction); - pFunction->setInternalFunction(bInternal); - pParentClass->setClassNotBuilt(true); - - KviPointerList lInheritedClasses; - lInheritedClasses.setAutoDelete(false); - searchInheritedClasses(szClassName,lInheritedClasses); - for(unsigned int i=0; i < lInheritedClasses.count(); i++) - lInheritedClasses.at(i)->setClassNotBuilt(true); - activateItem(pFunction); -} - -KviClassEditorTreeWidgetItem * KviClassEditor::findFunction(const QString & szFunctionName, KviClassEditorTreeWidgetItem * pClass) -{ - for(int i=0; i < pClass->childCount(); i++) - { - if(KviQString::equalCI(szFunctionName,((KviClassEditorTreeWidgetItem *)pClass->child(i))->name())) - return (KviClassEditorTreeWidgetItem *) pClass->child(i); - } - return 0; -} - -void KviClassEditor::renameItem() -{ - if(!m_pLastEditedItem) - return; - if(m_pLastEditedItem->isClass()) - renameClass(m_pLastEditedItem); - else if(m_pLastEditedItem->isNamespace()) - renameNamespace(m_pLastEditedItem); - else { - // is function - KviClassEditorTreeWidgetItem * pParent = (KviClassEditorTreeWidgetItem *)m_pLastEditedItem->parent(); - if(pParent->isClass()) - renameClass(pParent); - } -} - -void KviClassEditor::renameClass(KviClassEditorTreeWidgetItem * pClassItem) -{ - QString szClassName = buildFullClassName(pClassItem); - QString szNewClassName = szClassName; - - QString szInheritsClassName = pClassItem->inheritsClass(); - QString szNewInheritsClassName = szInheritsClassName; - bool bOk = askForClassName(szNewClassName,szNewInheritsClassName,true); - if(!bOk) - return; - if(classExists(szNewClassName) && KviQString::equalCS(szClassName,szNewClassName) && KviQString::equalCS(szInheritsClassName,szNewInheritsClassName)) - { - g_pClassEditorModule->lock(); - QMessageBox::information(this, - __tr2qs_ctx("Class already exists","editor"), - __tr2qs_ctx("This name is already in use. Please choose another one.","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - g_pClassEditorModule->unlock(); - return; - } - /*if(szNewClassName.tmp.indexOf("@@",Qt::CaseInsensitive) != -1) - { - g_pClassEditorModule->lock(); - QMessageBox::information(this, - __tr2qs_ctx("Bad Namespace Name","editor"), - __tr2qs_ctx("Found an empty namespace in namespace name","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - g_pClassEditorModule->unlock(); - szNewName = ""; - continue; - }*/ - KviClassEditorTreeWidgetItem * pNewItem = 0; - m_pClasses->removeRef(pClassItem); - cutItem(pClassItem); - if(szNewClassName.contains("::")) - { - pNewItem = createFullNamespace(szNewClassName.left(szNewClassName.lastIndexOf("::"))); - pClassItem->setName(szNewClassName.section("::",-1,-1)); - pNewItem->addChild(pClassItem); - } else { - pClassItem->setName(szNewClassName); - m_pTreeWidget->addTopLevelItem(pClassItem); - } - m_pClasses->insert(szNewClassName,pClassItem); - pClassItem->setInheritsClass(szNewInheritsClassName); - pClassItem->setClassNotBuilt(true); - - KviPointerList lInheritedClasses; - lInheritedClasses.setAutoDelete(false); - searchInheritedClasses(szClassName,lInheritedClasses); - for(unsigned int i=0; i < lInheritedClasses.count(); i++) - { - lInheritedClasses.at(i)->setClassNotBuilt(true); - lInheritedClasses.at(i)->setExpanded(true); - lInheritedClasses.at(i)->setInheritsClass(szNewClassName); - } - - if(pNewItem) - { - activateItem(pNewItem); - pNewItem->setExpanded(true); - } else { - activateItem(pClassItem); - pClassItem->setExpanded(true); - } - - qDebug("delete class %s caused by rename",szClassName.toUtf8().data()); - KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(szClassName); - if(pClass) - KviKvsKernel::instance()->objectController()->deleteClass(pClass); -} - -void KviClassEditor::cutItem(KviClassEditorTreeWidgetItem * pItem) -{ - int iIdx = m_pTreeWidget->indexOfTopLevelItem(pItem); - if(iIdx!=-1) - m_pTreeWidget->takeTopLevelItem(iIdx); - else { - KviClassEditorTreeWidgetItem * pParent = (KviClassEditorTreeWidgetItem *)pItem->parent(); - pParent->removeChild(pItem); - } -} - -void KviClassEditor::renameNamespace(KviClassEditorTreeWidgetItem * pOldNamespaceItem) -{ - QString szOldNameSpaceName = buildFullClassName(m_pLastEditedItem); - QString szNewNameSpaceName; - if(!askForNamespaceName(__tr2qs_ctx("Rename Namespace","editor"),__tr2qs_ctx("Please enter the new name for the namespace","editor"),szOldNameSpaceName,szNewNameSpaceName)) - return; - if(KviQString::equalCI(szOldNameSpaceName,szNewNameSpaceName)) - return; - KviClassEditorTreeWidgetItem * pNewItem = findItem(szNewNameSpaceName); - if(pNewItem) - { - g_pClassEditorModule->lock(); - if(pNewItem->isClass()) - { - QMessageBox::information(this, - __tr2qs_ctx("Name already exists as Class name","editor"), - __tr2qs_ctx("This name is already in use as Class name. Please choose another one.","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - } else { - QMessageBox::information(this, - __tr2qs_ctx("Namespace already exists","editor"), - __tr2qs_ctx("This name is already in use. Please choose another one.","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - } - g_pClassEditorModule->unlock(); - return; - } - KviPointerList pList; - pList.setAutoDelete(false); - appendAllClassItemsRecursive(&pList,pOldNamespaceItem); - cutItem(pOldNamespaceItem); - if(szNewNameSpaceName.contains("::")) - { - pNewItem=createFullNamespace(szNewNameSpaceName.left(szNewNameSpaceName.lastIndexOf("::"))); - pOldNamespaceItem->setName(szNewNameSpaceName.section("::",-1,-1)); - pNewItem->addChild(pOldNamespaceItem); - } else { - m_pTreeWidget->addTopLevelItem(pOldNamespaceItem); - pOldNamespaceItem->setName(szNewNameSpaceName); - } - for(unsigned int u=0; u < pList.count(); u++) - { - KviPointerHashTableEntry * pEntry = m_pClasses->findRef(pList.at(u)); - if(pEntry) - { - KviPointerList lInheritedClasses; - lInheritedClasses.setAutoDelete(false); - - QString szOldName = pEntry->key(); - QString szNewName = buildFullClassName(pList.at(u)); - searchInheritedClasses(szOldName,lInheritedClasses); - for(unsigned int v=0; v < lInheritedClasses.count(); v++) - { - lInheritedClasses.at(v)->setClassNotBuilt(true); - lInheritedClasses.at(v)->setExpanded(true); - lInheritedClasses.at(v)->setInheritsClass(szNewName); - } - m_pClasses->removeRef(pList.at(u)); - m_pClasses->insert(szNewName,pList.at(u)); - pList.at(u)->setClassNotBuilt(true); - - KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(szOldName); - if(pClass) - KviKvsKernel::instance()->objectController()->deleteClass(pClass); - } - } - - if(pNewItem) - { - activateItem(pNewItem); - pNewItem->setExpanded(true); - } else { - activateItem(pOldNamespaceItem); - pOldNamespaceItem->setExpanded(true); - } - //searchReplace(szOldNameSpaceName+"::",true,szNewNameSpaceName+"::"); -} - -void KviClassEditor::saveLastEditedItem() -{ - if(!m_pLastEditedItem) - return; - if(!m_pEditor->isModified() || m_pLastEditedItem->isNamespace() || m_pLastEditedItem->isClass()) - return; - ((KviClassEditorTreeWidgetItem *)m_pLastEditedItem)->setCursorPosition(m_pEditor->getCursor()); - QString newCode; - m_pEditor->getText(newCode); - ((KviClassEditorTreeWidgetItem *)m_pLastEditedItem)->setBuffer(newCode); - ((KviClassEditorTreeWidgetItem *)m_pLastEditedItem->parent())->setClassNotBuilt(true); -} - -void KviClassEditor::currentItemChanged(QTreeWidgetItem * pTree, QTreeWidgetItem *) -{ - saveLastEditedItem(); - m_pLastEditedItem = (KviClassEditorTreeWidgetItem *)pTree; - if(!m_pLastEditedItem) - { - m_pClassNameLabel->setText(__tr2qs_ctx("No item selected","editor")); - m_pClassNameRenameButton->setEnabled(false); - m_pEditor->setText(""); - m_pEditor->setEnabled(false); - return; - } - - KviClassEditorTreeWidgetItem * pClassItem = 0; - if(m_pLastEditedItem->isMethod()) - pClassItem = (KviClassEditorTreeWidgetItem *)m_pLastEditedItem->parent(); - else - pClassItem = m_pLastEditedItem; - - QString szClassName = buildFullClassName(pClassItem); - - if(m_pLastEditedItem->isNamespace()) - { - QString szLabelText = __tr2qs_ctx("Namespace","editor"); - szLabelText += ": "; - szLabelText += szClassName; - szLabelText += ""; - m_pClassNameLabel->setText(szLabelText); - m_pClassNameRenameButton->setEnabled(true); - m_pFunctionNameRenameButton->setEnabled(false); - //m_pinheritsClassNameLabel->setText(""); - m_pFunctionNameLabel->setText(""); - m_pEditor->setText(""); - m_pEditor->setEnabled(false); - m_pTreeWidget->setFocus(); - return; - } - - QString szLabelText = __tr2qs_ctx("Class","editor"); - szLabelText += ": "; - szLabelText += szClassName; - szLabelText += ", "; - szLabelText += __tr2qs_ctx("inherits from class ","editor"); - szLabelText += ": "; - szLabelText += pClassItem->inheritsClass(); - szLabelText += ""; - m_pClassNameLabel->setText(szLabelText); - - szLabelText = __tr2qs_ctx("Member Function","editor"); - if(m_pLastEditedItem->isMethod()) - { - szLabelText += ": "; - szLabelText += m_pLastEditedItem->text(0); - szLabelText += ""; - m_pFunctionNameRenameButton->setEnabled(true); - if(m_pLastEditedItem->reminder().isEmpty()) - m_pReminderLabel->hide(); - else { - QString szReminderText =__tr2qs_ctx("Reminder text.","editor"); - szReminderText += ": "; - szReminderText += m_pLastEditedItem->reminder(); - szReminderText += ""; - m_pReminderLabel->setText(szReminderText); - m_pReminderLabel->show(); - } - - m_pFunctionNameLabel->setText(szLabelText); - m_pFunctionNameLabel->show(); - m_pFunctionNameRenameButton->show(); - } else { - m_pReminderLabel->hide(); - m_pFunctionNameLabel->hide(); - m_pClassNameRenameButton->setEnabled(true); - m_pFunctionNameRenameButton->hide(); - } - if(m_pLastEditedItem->isClass()) - { - m_pFunctionNameRenameButton->setEnabled(false); - m_pEditor->setText(""); - m_pEditor->setEnabled(true); - m_pTreeWidget->setFocus(); - QString szBuffer; - QStringList szFunctionsList; - KviPointerHashTable lFunctions; - lFunctions.setAutoDelete(false); - - KviClassEditorTreeWidgetItem * pItem = 0; - for(int i=0; i < pTree->childCount(); i++) - { - pItem = ((KviClassEditorTreeWidgetItem *)pTree->child(i)); - szFunctionsList.append(pItem->name()); - lFunctions.insert(pItem->name(),pItem); - } - szFunctionsList.sort(); - for(int i=0; i < szFunctionsList.count(); i++) - { - szBuffer += "Member Function: $" + szFunctionsList.at(i) + "
"; - if(!lFunctions.find(szFunctionsList.at(i))->reminder().isEmpty()) - szBuffer+="Parameters reminder: "+lFunctions.find(szFunctionsList.at(i))->reminder()+"
"; - szBuffer+="
"; - } - m_pEditor->setUnHighlightedText(szBuffer); - m_pEditor->setReadOnly(true); - return; - } - m_pEditor->setReadOnly(false); - m_pEditor->setText(((KviClassEditorTreeWidgetItem *)pTree)->buffer()); - m_pEditor->setFocus(); - m_pEditor->setCursorPosition(((KviClassEditorTreeWidgetItem *)pTree)->cursorPosition()); - m_pEditor->setEnabled(true); -} - -void KviClassEditor::customContextMenuRequested(QPoint pnt) -{ - m_pContextPopup->clear(); - - m_pLastClickedItem = (KviClassEditorTreeWidgetItem *)m_pTreeWidget->itemAt(pnt); - - int iId; - iId = m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE)), - __tr2qs_ctx("Add Namespace","editor"), - this,SLOT(newNamespace())); - if(!m_pLastClickedItem) - m_pContextPopup->setItemEnabled(iId,true); - else - m_pContextPopup->setItemEnabled(iId,m_pLastClickedItem->isNamespace()); - - iId = m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASS)), - __tr2qs_ctx("Add Class","editor"), - this,SLOT(newClass())); - if(!m_pLastClickedItem) - m_pContextPopup->setItemEnabled(iId,true); - else - m_pContextPopup->setItemEnabled(iId,m_pLastClickedItem->isNamespace()); - - iId = m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FUNCTION)), - __tr2qs_ctx("Add Member Function","editor"), - this,SLOT(newMemberFunction())); - if(!m_pLastClickedItem) - m_pContextPopup->setItemEnabled(iId,false); - else - m_pContextPopup->setItemEnabled(iId,m_pLastClickedItem->isClass()| m_pLastClickedItem->isMethod()); - - bool bHasItems = m_pTreeWidget->topLevelItemCount(); - bool bHasSelected = hasSelectedItems(); - - m_pContextPopup->insertSeparator(); - - iId = m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)), - __tr2qs_ctx("Remove Selected","editor"), - this,SLOT(removeSelectedItems())); - m_pContextPopup->setItemEnabled(iId,bHasSelected); - - m_pContextPopup->insertSeparator(); - - m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)), - __tr2qs_ctx("Export Selected...","editor"), - this,SLOT(exportSelected())); - m_pContextPopup->setItemEnabled(iId,bHasSelected); - - m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)), - __tr2qs_ctx("Export Selected in singles files...","editor"), - this,SLOT(exportSelectedSepFiles())); - - m_pContextPopup->setItemEnabled(iId,bHasSelected); - - m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)), - __tr2qs_ctx("Export All...","editor"), - this,SLOT(exportAll())); - m_pContextPopup->setItemEnabled(iId,bHasItems); - - m_pContextPopup->insertSeparator(); - - m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_SEARCH)), - __tr2qs_ctx("Find In Classes...","editor"), - this,SLOT(slotFind())); - m_pContextPopup->setItemEnabled(iId,bHasItems); - - m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE)), - __tr2qs_ctx("Collapse All Items","editor"), - this,SLOT(slotCollapseItems())); - - m_pContextPopup->setItemEnabled(iId,bHasItems); - m_pContextPopup->popup(m_pTreeWidget->mapToGlobal(pnt)); -} - -void KviClassEditor::searchReplace(const QString & szSearch, bool bReplace, const QString & szReplace) -{ - KviPointerHashTableIterator it (*m_pClasses); - while(it.current()) - { - KviClassEditorTreeWidgetItem * pItem = it.current(); - for(int j=0; j < pItem->childCount(); j++) - { - bool bOpened = false; - if(((KviClassEditorTreeWidgetItem *)pItem->child(j))->buffer().indexOf(szSearch,0,Qt::CaseInsensitive) != -1) - { - pItem->child(j)->setBackground(0, QColor(255,0,0,128)); - if(bReplace) - { - QString &buffer=(QString &)((KviClassEditorTreeWidgetItem *)pItem->child(j))->buffer(); - pItem->setClassNotBuilt(true); - buffer.replace(szSearch,szReplace,Qt::CaseInsensitive); - } - if(!bOpened) - { - openParentItems(pItem->child(j)); - bOpened = true; - } - } else { - pItem->child(j)->setBackground(0, QColor(255,255,255)); - } - } - ++it; - } -} - -void KviClassEditor::slotFind() -{ - g_pClassEditorModule->lock(); - bool bOk; - - QString szSearch = QInputDialog::getText(this, - __tr2qs_ctx("Find In Classes","editor"), - __tr2qs_ctx("Please enter the text to be searched for. The matching function will be highlighted.","editor"), - QLineEdit::Normal, - "", - &bOk); - - g_pClassEditorModule->unlock(); - if(!bOk) - return; - if(szSearch.isEmpty()) - return; - m_pEditor->setFindText(szSearch); - searchReplace(szSearch); -} - -void KviClassEditor::slotFindWord(const QString & szSearch) -{ - m_pEditor->setFindText(szSearch); -} - -void KviClassEditor::recursiveCollapseItems(KviClassEditorTreeWidgetItem * pItem) -{ - if(!pItem) - return; - for(int i=0; i < pItem->childCount(); i++) - { - if(pItem->child(i)->childCount()) - { - pItem->child(i)->setExpanded(false); - recursiveCollapseItems((KviClassEditorTreeWidgetItem *)pItem->child(i)); - } - } -} - -void KviClassEditor::slotCollapseItems() -{ - for(int i=0; i < m_pTreeWidget->topLevelItemCount(); i++) - { - if(m_pTreeWidget->topLevelItem(i)->childCount()) - { - m_pTreeWidget->topLevelItem(i)->setExpanded(false); - recursiveCollapseItems((KviClassEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i)); - } - } -} - -void KviClassEditor::slotReplaceAll(const QString & szFind, const QString & szReplace) -{ - m_pEditor->setFindText(szReplace); - searchReplace(szFind,true,szReplace); - /* - for (int i=0;itopLevelItemCount();i++) - { - recursiveSearchReplace(szFind,(KviClassEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i),true,szReplace); - } - */ -} - -void KviClassEditor::exportClassBuffer(QString & szBuffer, KviClassEditorTreeWidgetItem * pItem) -{ - QString szTmp = pItem->buffer(); - KviCommandFormatter::blockFromBuffer(szTmp); - QString szName = buildFullClassName(pItem); - - szBuffer = "class(\""; - szBuffer += szName; - if(!pItem->inheritsClass().isEmpty()) - { - szBuffer += "\",\""; - szBuffer += pItem->inheritsClass(); - } - szBuffer += "\")\n{\n"; - for(int i=0; i < pItem->childCount(); i++) - { - KviClassEditorTreeWidgetItem * pFunction = (KviClassEditorTreeWidgetItem *)pItem->child(i); - if(pFunction->isMethod()) - { - szBuffer += "\t"; - if(pFunction->isInternalFunction()) - szBuffer += "internal "; - szBuffer += "function "; - szBuffer += pFunction->name(); - szBuffer += "(" + pFunction->reminder() + ")"; - szBuffer += "\n\t{\n"; - szBuffer += pFunction->buffer(); - szBuffer += "\n\t}\n"; - } - } - szBuffer += "}\n"; -} - -void KviClassEditor::exportAll() -{ - exportClasses(false); -} - -void KviClassEditor::exportSelectedSepFiles() -{ - exportClasses(true,true); -} - -void KviClassEditor::exportSelected() -{ - exportClasses(true); -} - -void KviClassEditor::exportSelectionInSinglesFiles(KviPointerList * pList) -{ - bool bReplaceAll = false; - - if(!m_szDir.endsWith(QString(KVI_PATH_SEPARATOR))) - m_szDir += KVI_PATH_SEPARATOR; - if(!pList->first()) - { - g_pClassEditorModule->lock(); - QMessageBox::warning(this,__tr2qs_ctx("Class Export","editor"),__tr2qs_ctx("There is no selection!","editor"),__tr2qs_ctx("OK","editor")); - g_pClassEditorModule->unlock(); - return; - } - g_pClassEditorModule->lock(); - - if(!KviFileDialog::askForDirectoryName(m_szDir,__tr2qs_ctx("Choose a Directory - KVIrc","editor"),m_szDir)) - { - g_pClassEditorModule->unlock(); - return; - } - - if(!m_szDir.endsWith(QString(KVI_PATH_SEPARATOR))) - m_szDir += KVI_PATH_SEPARATOR; - - for(KviClassEditorTreeWidgetItem * pItem = pList->first(); pItem; pItem = pList->next()) - { - QString szTmp; - exportClassBuffer(szTmp,pItem); - QString szFileName = buildFullClassName(pItem); - szFileName += ".kvs"; - szFileName.replace("::","_"); - QString szCompletePath = m_szDir+szFileName; - if(KviFileUtils::fileExists(szCompletePath) && !bReplaceAll) - { - QString szMsg = __tr2qs_ctx("The file \"%1\" exists. Do you want to replace it?","editor").arg(szFileName); - int iRet = QMessageBox::question(this,__tr2qs_ctx("Replace file","editor"),szMsg,__tr2qs_ctx("Yes","editor"),__tr2qs_ctx("Yes to All","editor"),__tr2qs_ctx("No","editor")); - if(iRet != 2) - { - KviFileUtils::writeFile(szCompletePath,szTmp); - if(iRet == 1) - bReplaceAll = true; - } - } - else - KviFileUtils::writeFile(szCompletePath,szTmp); - } - g_pClassEditorModule->unlock(); -} - -void KviClassEditor::exportClasses(bool bSelectedOnly, bool bSingleFiles) -{ - QString szOut; - QString szNameFile; - QString szFile; - int iCount = 0; - - saveLastEditedItem(); - - KviPointerList list; - list.setAutoDelete(false); - - if(bSelectedOnly) - appendSelectedClassItems(&list); - else - appendAllClassItems(&list); - - if(bSingleFiles) - { - exportSelectionInSinglesFiles(&list); - return; - } - - KviClassEditorTreeWidgetItem * pTempItem = 0; - for(KviClassEditorTreeWidgetItem * pItem = list.first(); pItem; pItem = list.next()) - { - pTempItem = pItem; - iCount++; - QString szTmp; - exportClassBuffer(szTmp,pItem); - szOut += szTmp; - szOut += "\n"; - } - - if(szOut.isEmpty()) - { - g_pClassEditorModule->lock(); - QMessageBox::warning(this,__tr2qs_ctx("Class Export","editor"),__tr2qs_ctx("The exported file would be empty: cowardly refusing to write it","editor"),__tr2qs_ctx("OK","editor")); - g_pClassEditorModule->unlock(); - return; - } - - QString szName = m_szDir; - - if(!szName.endsWith(QString(KVI_PATH_SEPARATOR))) - szName += KVI_PATH_SEPARATOR; - - g_pClassEditorModule->lock(); - - if(iCount != 1) - szNameFile = "classes"; - else { - QString szTmp = buildFullClassName(pTempItem); - szNameFile = szTmp.replace("::","_"); - } - - szName += szNameFile; - szName += ".kvs"; - if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs_ctx("Choose a Filename - KVIrc","editor"),szName,KVI_FILTER_SCRIPT,false,true,true)) - { - g_pClassEditorModule->unlock(); - return; - } - m_szDir=QFileInfo(szFile).absolutePath(); - g_pClassEditorModule->unlock(); - - if(!KviFileUtils::writeFile(szFile,szOut)) - { - g_pClassEditorModule->lock(); - QMessageBox::warning(this,__tr2qs_ctx("Write Failed - KVIrc","editor"),__tr2qs_ctx("Unable to write to the class file.","editor"),__tr2qs_ctx("OK","editor")); - g_pClassEditorModule->unlock(); - } -} - -void KviClassEditor::saveProperties(KviConfigurationFile * pCfg) -{ - pCfg->writeEntry("Sizes",m_pSplitter->sizes()); - QString szName; - if(m_pLastEditedItem) - szName = buildFullClassName(m_pLastEditedItem); - pCfg->writeEntry("LastClass",szName); -} - -void KviClassEditor::loadProperties(KviConfigurationFile * pCfg) -{ - QList def; - def.append(20); - def.append(80); - m_pSplitter->setSizes(pCfg->readIntListEntry("Sizes",def)); - QString szTmp = pCfg->readEntry("LastClass",QString()); - - KviClassEditorTreeWidgetItem * pItem = findItem(szTmp); - activateItem(pItem); -} - -void KviClassEditor::appendSelectedClassItems(KviPointerList * pList) -{ - QList list = m_pTreeWidget->selectedItems(); - for(int i=0; i < list.count(); i++) - { - if(((KviClassEditorTreeWidgetItem *)list.at(i))->isClass()) - pList->append((KviClassEditorTreeWidgetItem *)list.at(i)); - else appendSelectedClassItemsRecursive(pList,list.at(i)); - } -} - -void KviClassEditor::appendSelectedClassItemsRecursive(KviPointerList * pList, QTreeWidgetItem * pStartFrom) -{ - for(int i=0; i < pStartFrom->childCount(); i++) - { - if(((KviClassEditorTreeWidgetItem *)pStartFrom->child(i))->isClass()) - pList->append(((KviClassEditorTreeWidgetItem *)pStartFrom->child(i))); - else - appendSelectedClassItemsRecursive(pList,pStartFrom->child(i)); - } -} - -void KviClassEditor::appendAllClassItems(KviPointerList * pList) -{ - KviPointerHashTableIterator it (*m_pClasses); - while(it.current()) - { - pList->append(it.current()); - ++it; - } -} - -void KviClassEditor::appendAllClassItemsRecursive(KviPointerList * pList, QTreeWidgetItem * pStartFrom) -{ - for(int i=0; i < pStartFrom->childCount(); i++) - { - if(((KviClassEditorTreeWidgetItem *)pStartFrom->child(i))->isClass()) - { - pList->append((KviClassEditorTreeWidgetItem *)pStartFrom->child(i)); - } else { - appendAllClassItemsRecursive(pList,pStartFrom->child(i)); - } - } -} - -void KviClassEditor::removeItemChildren(KviClassEditorTreeWidgetItem * pItem, KviPointerList & lRemovedItems) -{ - if(pItem->isClass()) - { - KviPointerList lInheritedClasses; - lInheritedClasses.setAutoDelete(false); - searchInheritedClasses(buildFullClassName(pItem),lInheritedClasses); - for(unsigned int u=0; u < lInheritedClasses.count(); u++) - { - lInheritedClasses.at(u)->setClassNotBuilt(true); - lInheritedClasses.at(u)->setExpanded(true); - lInheritedClasses.at(u)->setInheritsClass("object"); - } - } - - while(pItem->childCount() > 0) - { - KviClassEditorTreeWidgetItem * pChild = (KviClassEditorTreeWidgetItem *)(pItem->child(0)); - if(pChild->childCount()) - removeItemChildren(pChild,lRemovedItems); - if(pChild->isClass()) - { - m_pClasses->removeRef(pChild); - KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(buildFullClassName(pChild)); - if(pClass) - KviKvsKernel::instance()->objectController()->deleteClass(pClass); - qDebug("removing class %s %p",buildFullClassName(pChild).toUtf8().data(), pClass); - } - pItem->removeChild(pChild); - lRemovedItems.append(pItem); - delete pChild; - } -} - -bool KviClassEditor::removeItem(KviClassEditorTreeWidgetItem * pItem, KviPointerList & lRemovedItems, bool * pbYesToAll) -{ - if(!pItem) - return true; - QString szMsg; - QString szName = pItem->name(); - - if(!*pbYesToAll) - { - saveLastEditedItem(); - if(pItem->isClass()) - { - KviQString::sprintf(szMsg,__tr2qs_ctx("Do you really want to remove the class \"%Q\" ?","editor"),&szName); - } else if(pItem->isNamespace()) - { - KviQString::sprintf(szMsg,__tr2qs_ctx("Do you really want to remove the namespace \"%Q\" ?","editor"),&szName); - szMsg += "
"; - szMsg += __tr2qs_ctx("Please note that all the children classes/functions will be deleted too.","editor"); - } else if(pItem->isMethod()) - { - KviQString::sprintf(szMsg,__tr2qs_ctx("Do you really want to remove the function \"%Q\" ?","editor"),&szName); - } - - g_pClassEditorModule->lock(); - int iRet = QMessageBox::question(this,__tr2qs_ctx("Remove item","editor"),szMsg,__tr2qs_ctx("Yes","editor"),__tr2qs_ctx("Yes to All","editor"),__tr2qs_ctx("No","editor")); - g_pClassEditorModule->unlock(); - switch(iRet) - { - case 0: - // nothing - break; - case 1: - *pbYesToAll = true; - break; - default: - return false; - break; - } - } - - if(pItem == m_pLastEditedItem) - m_pLastEditedItem = 0; - if(pItem == m_pLastClickedItem) - m_pLastClickedItem = 0; - if(pItem->childCount()) - removeItemChildren(pItem,lRemovedItems); - if(pItem->isClass()) - { - m_pClasses->removeRef(pItem); - KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(buildFullClassName(pItem)); - qDebug("rimuovo class %s %p",buildFullClassName(pItem).toUtf8().data(), pClass); - if(pClass) - KviKvsKernel::instance()->objectController()->deleteClass(pClass); - else - { - QString szFileName = buildFullClassName(pItem); - szFileName.replace("::","--"); - szFileName.append(KVI_FILEEXTENSION_SCRIPT); - QString szPath; - g_pApp->getLocalKvircDirectory(szPath,KviApplication::Classes); - QDir d(szPath); - if(d.exists(szFileName)) - { - qDebug("rimuovo dal disco il file %s",szFileName.toUtf8().data()); - d.remove(szFileName); - } - } - } - if(pItem->isMethod()) - { - updateClassHierarchy((KviClassEditorTreeWidgetItem *)pItem->parent()); - } - lRemovedItems.append(pItem); - delete pItem; - return true; -} - -void KviClassEditor::updateClassHierarchy(KviClassEditorTreeWidgetItem * pClass) -{ - pClass->setClassNotBuilt(true); - KviPointerList lInheritedClasses; - lInheritedClasses.setAutoDelete(false); - searchInheritedClasses(pClass->name(),lInheritedClasses); - for(unsigned int u=0; u < lInheritedClasses.count(); u++) - { - lInheritedClasses.at(u)->setClassNotBuilt(true); - lInheritedClasses.at(u)->setInheritsClass(pClass->name()); - lInheritedClasses.at(u)->setExpanded(true); - } -} - -void KviClassEditor::removeSelectedItems() -{ - KviPointerList lRemovedItems; - lRemovedItems.setAutoDelete(false); - QList list = m_pTreeWidget->selectedItems(); - bool bYesToAll = false; - for(int i=0; i < list.count(); i++) - { - if(lRemovedItems.findRef((KviClassEditorTreeWidgetItem *) list.at(i)) != -1) - continue; - if(!removeItem((KviClassEditorTreeWidgetItem *) list.at(i),lRemovedItems,&bYesToAll)) - return; - } -} - -bool KviClassEditor::askForClassName(QString & szClassName, QString & szInheritsClassName, bool bEdit) -{ - KviClassEditorDialog * pDialog = new KviClassEditorDialog(this,"classdialog",m_pClasses,szClassName,szInheritsClassName,bEdit); - szClassName = ""; - g_pClassEditorModule->lock(); - bool bOk = pDialog->exec(); - g_pClassEditorModule->unlock(); - if(bOk) - { - szClassName = pDialog->className(); - szInheritsClassName = pDialog->inheritsClassName(); - delete pDialog; - return true; - } - delete pDialog; - return false; -} - -bool KviClassEditor::askForFunction(QString & szFunctionName, QString & szReminder, bool * bInternal, const QString & szClassName, bool bRenameMode) -{ - KviClassEditorFunctionDialog * pDialog = new KviClassEditorFunctionDialog(this,"function",szClassName,szFunctionName,szReminder,*bInternal, bRenameMode); - szFunctionName = ""; - g_pClassEditorModule->lock(); - bool bOk = pDialog->exec(); - g_pClassEditorModule->unlock(); - if(bOk) - { - szFunctionName = pDialog->functionName(); - szReminder = pDialog->reminder(); - *bInternal = pDialog->isInternalFunction(); - delete pDialog; - return true; - } - delete pDialog; - return false; -} - -bool KviClassEditor::askForNamespaceName(const QString & szAction, const QString & szText, const QString & szInitialText, QString & szNewName) -{ - bool bOk = false; - while(szNewName.isEmpty()) - { - g_pClassEditorModule->lock(); - szNewName = QInputDialog::getText(this, - szAction, - szText, - QLineEdit::Normal, - szInitialText, - &bOk); - g_pClassEditorModule->unlock(); - if(!bOk) - return false; - if(szNewName.isEmpty()) - { - g_pClassEditorModule->lock(); - QMessageBox::warning(this, - __tr2qs_ctx("Missing Namespace Name","editor"), - __tr2qs_ctx("You must specify a valid name for the namespace","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - g_pClassEditorModule->unlock(); - continue; - } - - // we allow only [\w:]+ - QRegExp re("[\\w:]+"); - if(!re.exactMatch(szNewName)) - { - g_pClassEditorModule->lock(); - QMessageBox::information(this, - __tr2qs_ctx("Bad Namespace Name","editor"), - __tr2qs_ctx("Namespace names can contain only letters, digits, underscores and '::' namespace separators","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - g_pClassEditorModule->unlock(); - szNewName = ""; - continue; - } - // make sure that we have only doubled "::" and not ":" or ":::..." - QString szTmp = szNewName; - szTmp.replace("::","@"); // @ is not allowed by the rule above - if(szTmp.indexOf(":",Qt::CaseInsensitive) != -1) - { - g_pClassEditorModule->lock(); - QMessageBox::information(this, - __tr2qs_ctx("Bad Namespace Name","editor"), - __tr2qs_ctx("Stray ':' character in namespace name: did you mean ...:: ?","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - g_pClassEditorModule->unlock(); - szNewName = ""; - continue; - } - if(szTmp.indexOf("@@",Qt::CaseInsensitive) != -1) - { - g_pClassEditorModule->lock(); - QMessageBox::information(this, - __tr2qs_ctx("Bad Namespace Name","editor"), - __tr2qs_ctx("Found an empty namespace in namespace name","editor"), - __tr2qs_ctx("Ok, Let me try again...","editor")); - g_pClassEditorModule->unlock(); - szNewName = ""; - continue; - } - } - return true; -} - -void KviClassEditor::openParentItems(QTreeWidgetItem * pItem) -{ - if(pItem->parent()) - { - pItem->parent()->setExpanded(true); - openParentItems(pItem->parent()); - } -} - -void KviClassEditor::activateItem(QTreeWidgetItem * pItem) -{ - if(!pItem) - return; - openParentItems(pItem); - m_pTreeWidget->setCurrentItem(pItem); -} - -void KviClassEditor::newClass() -{ - QString szClassName; - QString szinheritsClassName; - askForClassName(szClassName,szinheritsClassName,false); - if(szClassName.isEmpty()) - return; - KviClassEditorTreeWidgetItem * pItem = newItem(szClassName,KviClassEditorTreeWidgetItem::Class); - - KviQString::escapeKvs(&szClassName, KviQString::EscapeSpace); - KviQString::escapeKvs(&szinheritsClassName, KviQString::EscapeSpace); - - QString szClass = "class("; - szClass += szClassName + "," + szinheritsClassName; - szClass += "){}\n"; - pItem->setInheritsClass(szinheritsClassName); - activateItem(pItem); - m_pClasses->insert(szClassName,pItem); - KviKvsScript::run(szClass,g_pActiveWindow); -} - -void KviClassEditor::newNamespace() -{ - QString szName; - if(!askForNamespaceName(__tr2qs_ctx("Add Namespace","editor"),__tr2qs_ctx("Please enter the name for the new namespace","editor"),"mynamespace",szName)) - return; - if(szName.isEmpty()) - return; - KviClassEditorTreeWidgetItem * pItem = newItem(szName,KviClassEditorTreeWidgetItem::Namespace); - activateItem(pItem); -} - -void KviClassEditor::newMemberFunction() -{ - QString szFunctionName; - QString szClassName; - QString szReminder; - - if(m_pLastClickedItem->isMethod()) - m_pLastClickedItem = (KviClassEditorTreeWidgetItem*)m_pLastClickedItem->parent(); - szClassName = buildFullClassName(m_pLastClickedItem); - bool bInternal = false; - if(!askForFunction(szFunctionName, szReminder,&bInternal,szClassName,false)) - return; - if(szFunctionName.isEmpty()) - return; - - KviClassEditorTreeWidgetItem * pItem = newItem(szFunctionName,KviClassEditorTreeWidgetItem::Method); - pItem->setInternalFunction(bInternal); - if(!szReminder.isEmpty()) - pItem->setReminder(szReminder); - activateItem(pItem); - ((KviClassEditorTreeWidgetItem*)pItem->parent())->setClassNotBuilt(true); -} - -KviClassEditorTreeWidgetItem * KviClassEditor::newItem(QString & szName, KviClassEditorTreeWidgetItem::Type eType) -{ - if(m_pLastClickedItem) - buildFullItemPath(m_pLastClickedItem,szName); - - QString szTmp; - if(findItem(szName)) - szName.append("1"); - - int iIdx = 2; - while(findItem(szName)) - { - szTmp.setNum(iIdx); - szName.chop(szTmp.length()); - szName.append(szTmp); - iIdx++; - } - KviClassEditorTreeWidgetItem * pItem; - pItem = createFullItem(szName); - pItem->setType(eType); - return pItem; -} - -void KviClassEditor::build() -{ - saveLastEditedItem(); - KviPointerHashTableIterator it (*m_pClasses); - KviPointerList linkedClasses; - linkedClasses.setAutoDelete(false); - KviPointerList skipClasses; - skipClasses.setAutoDelete(false); - bool bErrorWhilecompiling = false; - while(it.current()) - { - KviClassEditorTreeWidgetItem * pClass = it.current(); - if(skipClasses.findRef(it.current()) != -1) - { - ++it; - continue; - } - if(pClass->classNotBuilt()) - { - //qDebug("compiling %s",pClass->name().toUtf8().data()); - KviClassEditorTreeWidgetItem * pParentClass = m_pClasses->find(pClass->inheritsClass()); - - linkedClasses.append(pClass); - //if (!pParentClass) qDebug("no parent class"); - while(pParentClass) - { - if(pParentClass->classNotBuilt()) - linkedClasses.append(pParentClass); - pParentClass = m_pClasses->find(pParentClass->inheritsClass()); - } - for(int i = linkedClasses.count()-1; i >= 0; i--) - { - QString szFullClassName = buildFullClassName(linkedClasses.at(i)); - KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(szFullClassName); - if(pClass) - KviKvsKernel::instance()->objectController()->deleteClass(pClass); - QString szClass; - exportClassBuffer(szClass, linkedClasses.at(i)); - KviKvsScript::run(szClass,g_pActiveWindow); - pClass = KviKvsKernel::instance()->objectController()->lookupClass(szFullClassName); - if(!pClass) - { - bErrorWhilecompiling = true; - QString szError = __tr2qs_ctx("Unable to compile class: ","editor"); - szError += szFullClassName + "\n"; - KviPointerList lInheritedClasses; - lInheritedClasses.setAutoDelete(false); - searchInheritedClasses(szFullClassName,lInheritedClasses); - if(lInheritedClasses.count()) - { - szError += __tr2qs_ctx("These inherited classes will be not compiled too:","editor"); - szError += "\n"; - for(unsigned int u=0; u < lInheritedClasses.count(); u++) - { - szError += buildFullClassName(lInheritedClasses.at(u)) + "\n"; - lInheritedClasses.at(u)->setClassNotBuilt(true); - skipClasses.append(lInheritedClasses.at(u)); - } - } - QMessageBox::critical(this,__tr2qs_ctx("Compilation error - KVIrc","editor"),szError, - QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton); - break; - } - //else qDebug("class compiled %s :\n",szClass.toUtf8().data()); - linkedClasses.at(i)->setClassNotBuilt(false); - m_pEditor->setModified(false); - } - } - ++it; - } - if(bErrorWhilecompiling) - saveNotBuiltClasses(); - else { - QString szFileName = "libkviclasseditortmp.kvc"; - QString szBuffer; - g_pApp->getLocalKvircDirectory(szBuffer,KviApplication::ConfigPlugins,szFileName); - KviConfigurationFile cfg(szBuffer,KviConfigurationFile::Write); - cfg.clear(); - cfg.sync(); - } - KviKvsKernel::instance()->objectController()->flushUserClasses(); -} - -void KviClassEditor::loadNotBuiltClasses() -{ - QString szFileName = "libkviclasseditortmp.kvc"; - QString szBuffer; - g_pApp->getLocalKvircDirectory(szBuffer,KviApplication::ConfigPlugins,szFileName); - KviConfigurationFile cfg(szBuffer,KviConfigurationFile::Read); - KviConfigurationFileIterator it(*(cfg.dict())); - - KviPointerList l; - l.setAutoDelete(true); - - while(it.current()) - { - l.append(new QString(it.currentKey())); - ++it; - } - - for(QString * pszTmp = l.first(); pszTmp; pszTmp = l.next()) - { - cfg.setGroup(*pszTmp); - KviClassEditorTreeWidgetItem * pClassItem = createFullItem(*pszTmp); - m_pClasses->insert(*pszTmp,pClassItem); - pClassItem->setClassNotBuilt(true); - KviConfigurationFileGroup * pDict = cfg.dict()->find(*pszTmp); - if(pDict) - { - KviConfigurationFileGroupIterator it(*pDict); - KviPointerList names; - names.setAutoDelete(true); - while(it.current()) - { - names.append(new QString(it.currentKey())); - ++it; - } - for(QString * pszTmp = names.first(); pszTmp; pszTmp = names.next()) - { - - if(KviQString::equalCI(*pszTmp,"@Inherits")) - { - pClassItem->setInheritsClass(cfg.readEntry(*pszTmp,"")); - continue; - } - if((*pszTmp).left(9) == "@Reminder") - continue; - QString szCode = cfg.readEntry(*pszTmp,""); - KviClassEditorTreeWidgetItem * pFunctionItem = findFunction(*pszTmp, pClassItem); - if(!pFunctionItem) - pFunctionItem = new KviClassEditorTreeWidgetItem(pClassItem,KviClassEditorTreeWidgetItem::Method,*pszTmp); - pFunctionItem->setBuffer(szCode); - QString szEntry = "@Reminder|" + (*pszTmp); - QString szReminder = cfg.readEntry(szEntry,""); - pFunctionItem->setReminder(szReminder); - } - } - } -} - -void KviClassEditor::saveNotBuiltClasses() -{ - saveLastEditedItem(); - KviPointerHashTableIterator it (*m_pClasses); - QString szFileName = "libkviclasseditortmp.kvc"; - QString szBuffer; - g_pApp->getLocalKvircDirectory(szBuffer,KviApplication::ConfigPlugins,szFileName); - KviConfigurationFile cfg(szBuffer,KviConfigurationFile::Write); - cfg.clear(); - - while(it.current()) - { - if(it.current()->classNotBuilt()) - { - KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(it.currentKey()); - if(pClass) - KviKvsKernel::instance()->objectController()->deleteClass(pClass); - - cfg.setGroup(it.currentKey()); - cfg.writeEntry("@Inherits",it.current()->inheritsClass()); - QString szReminderEntry; - for(int i=0; i < it.current()->childCount(); i++) - { - if(!((KviClassEditorTreeWidgetItem *)it.current()->child(i))->reminder().isEmpty()) - { - szReminderEntry="@Reminder|"+((KviClassEditorTreeWidgetItem *)it.current()->child(i))->name(); - cfg.writeEntry(szReminderEntry,((KviClassEditorTreeWidgetItem *)it.current()->child(i))->reminder()); - } - cfg.writeEntry(((KviClassEditorTreeWidgetItem *)it.current()->child(i))->name(),((KviClassEditorTreeWidgetItem *)it.current()->child(i))->buffer()); - } - } - ++it; - } - cfg.sync(); -} - -void KviClassEditor::searchInheritedClasses(const QString szClass, KviPointerList & lInheritedClasses) -{ - KviPointerHashTableIterator it (*m_pClasses); - while(it.current()) - { - if(KviQString::equalCI(szClass,it.current()->inheritsClass())) - lInheritedClasses.append(it.current()); - ++it; - } -} - -KviClassEditorWindow::KviClassEditorWindow(KviMainWindow * pFrm) -: KviWindow(KVI_WINDOW_TYPE_SCRIPTEDITOR,pFrm,"classeditor",0) -{ - g_pClassEditorWindow = this; - - setFixedCaption(__tr2qs_ctx("Class Editor","editor")); - - QGridLayout * pLayout = new QGridLayout(); - - m_pEditor = new KviClassEditor(this); - pLayout->addWidget(m_pEditor,0,0,1,4); - - QPushButton * pBtn = new QPushButton(__tr2qs_ctx("&Build","editor"),this); - pBtn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT))); - pLayout->addWidget(pBtn,1,1); - connect(pBtn,SIGNAL(clicked()),this,SLOT(buildClicked())); - - pBtn = new QPushButton(__tr2qs_ctx("&Save","editor"),this); - pBtn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT))); - pLayout->addWidget(pBtn,1,2); - connect(pBtn,SIGNAL(clicked()),this,SLOT(saveClicked())); - - pBtn = new QPushButton(__tr2qs_ctx("Close","editor"),this); - pBtn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD))); - pLayout->addWidget(pBtn,1,3); - connect(pBtn,SIGNAL(clicked()),this,SLOT(cancelClicked())); - - pLayout->setRowStretch(0,1); - pLayout->setColumnStretch(0,1); - setLayout(pLayout); -} - -KviClassEditorWindow::~KviClassEditorWindow() -{ - g_pClassEditorWindow = 0; -} - -void KviClassEditorWindow::buildClicked() -{ - m_pEditor->build(); -} - -void KviClassEditorWindow::saveClicked() -{ - m_pEditor->saveNotBuiltClasses(); -} - -void KviClassEditorWindow::cancelClicked() -{ - close(); -} - -QPixmap * KviClassEditorWindow::myIconPtr() -{ - return g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASSEDITOR); -} - -void KviClassEditorWindow::configGroupName(QString &szName) -{ - szName = "classeditor"; -} - -void KviClassEditorWindow::saveProperties(KviConfigurationFile * pCfg) -{ - m_pEditor->saveProperties(pCfg); -} - -void KviClassEditorWindow::loadProperties(KviConfigurationFile * pCfg) -{ - m_pEditor->loadProperties(pCfg); -} - -KviClassEditorDialog::KviClassEditorDialog(QWidget * pParent, const QString & szName, KviPointerHashTable * pClasses, const QString & szClassName, const QString & szInheritsClassName, bool bRenameMode) -: QDialog(pParent) -{ - setObjectName(szName); - - QGridLayout * pLayout = new QGridLayout(this); - - KviTalHBox * pHBox = new KviTalHBox(this); - pHBox->setSpacing(0); - pHBox->setMargin(0); - pLayout->addWidget(pHBox,0,0); - - QLabel * pLabel = new QLabel(pHBox); - pLabel->setObjectName("classnamelabel"); - pLabel->setText(__tr2qs_ctx("Please enter the name for the class:","editor")); - - m_pClassNameLineEdit = new QLineEdit(pHBox); - m_pClassNameLineEdit->setObjectName("classnameineedit"); - m_pClassNameLineEdit->setText(szClassName); - pLabel->setBuddy(m_pClassNameLineEdit); - QRegExp re; - if(!bRenameMode) - { - // we allow only [\w:]+ class name - re.setPattern("[\\w]+"); - m_pClassNameLineEdit->setToolTip(__tr2qs_ctx("Class names can contain only letters, digits and underscores","editor")); - } else { - // in editor mode we allow [\w:]+ and namespace separator - re.setPattern("[\\w]+(::[\\w]+)+"); - m_pClassNameLineEdit->setToolTip(__tr2qs_ctx("In rename mode class names can contain only letters, digits and underscores and namespaces :: separator","editor")); - } - QRegExpValidator * pValidator = new QRegExpValidator(re,this); - m_pClassNameLineEdit->setValidator(pValidator); - m_pClassNameLineEdit->setObjectName("functionameineedit"); - - pHBox = new KviTalHBox(this); - pHBox->setSpacing(0); - pHBox->setMargin(0); - pLayout->addWidget(pHBox,1,0); - - pLabel = new QLabel(pHBox); - pLabel->setObjectName("Inheritsclasslabel"); - pLabel->setText(__tr2qs_ctx("Inherits Class:","editor")); - - m_pInheritsClassComboBox = new QComboBox(pHBox); - pLabel->setBuddy(m_pInheritsClassComboBox); - - KviPointerHashTableIterator pClassesIt(*pClasses); - - QStringList szClasses; - while(pClassesIt.current()) - { - if(!KviQString::equalCI(pClassesIt.currentKey(),szClassName)) - szClasses.append(pClassesIt.currentKey()); - ++pClassesIt; - } - KviPointerHashTableIterator pBuiltinClasses(*KviKvsKernel::instance()->objectController()->classDict()); - while(pBuiltinClasses.current()) - { - if(pBuiltinClasses.current()->isBuiltin()) - szClasses.append(pBuiltinClasses.currentKey()); - ++pBuiltinClasses; - } - - int iCurrentIdx; - szClasses.sort(); - for(int i=0; i < szClasses.count(); i++) - m_pInheritsClassComboBox->addItem(szClasses.at(i)); - if(szInheritsClassName.isEmpty()) - iCurrentIdx = m_pInheritsClassComboBox->findText("object"); - else { - iCurrentIdx = m_pInheritsClassComboBox->findText(szInheritsClassName); - if(iCurrentIdx == -1) - iCurrentIdx = m_pInheritsClassComboBox->findText("object"); - } - m_pInheritsClassComboBox->setCurrentIndex(iCurrentIdx); - m_pClassNameLineEdit->setFocus(); - connect(m_pClassNameLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged(const QString &))); - - pHBox = new KviTalHBox(this); - pHBox->setSpacing(0); - pHBox->setMargin(0); - pLayout->addWidget(pHBox,2,0); - - m_pNewClassButton = new QPushButton(pHBox); - m_pNewClassButton->setObjectName("newclassbutton"); - if(bRenameMode) - m_pNewClassButton->setText(__tr2qs_ctx("&Rename Class","editor")); - else { - m_pNewClassButton->setText(__tr2qs_ctx("&Create Class","editor")); - m_pNewClassButton->setEnabled(false); - } - connect(m_pNewClassButton, SIGNAL(clicked()), this, SLOT(accept())); - - QPushButton * pCancelButton = new QPushButton(pHBox); - pCancelButton->setObjectName("cancelButton"); - pCancelButton->setText(__tr2qs_ctx("&Cancel","editor")); - connect(pCancelButton, SIGNAL(clicked()), this, SLOT(reject())); - - setLayout(pLayout); -} - -KviClassEditorDialog::~KviClassEditorDialog() -{ -} - -void KviClassEditorDialog::textChanged(const QString & szText) -{ - m_pNewClassButton->setEnabled(!szText.isEmpty()); -} - -KviClassEditorFunctionDialog::KviClassEditorFunctionDialog(QWidget * pParent, const QString & szName, const QString & szClassName, const QString & szFunctionName, const QString & szReminder, bool bIsInternal, bool bRenameMode) -: QDialog(pParent) -{ - setObjectName(szName); - - QGridLayout * pLayout = new QGridLayout(this); - - KviTalHBox * pHBox = new KviTalHBox(this); - pHBox->setSpacing(0); - pHBox->setMargin(0); - pLayout->addWidget(pHBox,0,0); - - QLabel * pLabel = new QLabel(pHBox); - pLabel->setObjectName("classnamelabel"); - pLabel->setText("Class: "+szClassName+""); - - pHBox = new KviTalHBox(this); - pHBox->setSpacing(0); - pHBox->setMargin(0); - pLayout->addWidget(pHBox,1,0); - - pLabel = new QLabel(pHBox); - pLabel->setObjectName("functionnamelabel"); - pLabel->setText(__tr2qs_ctx("Please enter the name for the member function:","editor")); - - m_pFunctionNameLineEdit = new QLineEdit(pHBox); - - // we allow only [\w:]+ function name - QRegExp re("[\\w]+"); - QRegExpValidator * pValidator = new QRegExpValidator(re,this); - m_pFunctionNameLineEdit->setValidator(pValidator); - m_pFunctionNameLineEdit->setObjectName("functionameineedit"); - m_pFunctionNameLineEdit->setToolTip(__tr2qs_ctx("Function names can contain only letters, digits and underscores","editor")); - m_pFunctionNameLineEdit->setText(szFunctionName); - pLabel->setBuddy(m_pFunctionNameLineEdit); - - pHBox = new KviTalHBox(this); - pHBox->setSpacing(0); - pHBox->setMargin(0); - pLayout->addWidget(pHBox,2,0); - - pLabel = new QLabel(pHBox); - pLabel->setObjectName("reminderlabel"); - pLabel->setWordWrap(1); - pLabel->setText(__tr2qs_ctx("Please enter the optional reminder string for the member function:","editor")); - - m_pReminderLineEdit = new QLineEdit(pHBox); - m_pReminderLineEdit->setText(szReminder); - pLabel->setBuddy(m_pReminderLineEdit); - - pHBox = new KviTalHBox(this); - pHBox->setSpacing(0); - pHBox->setMargin(0); - pLayout->addWidget(pHBox,3,0); - - pLabel = new QLabel(pHBox); - pLabel->setObjectName("functionnamelabel"); - pLabel->setText(__tr2qs_ctx("Set as Internal Function: ","editor")); - - m_pInternalCheckBox = new QCheckBox(pHBox); - m_pInternalCheckBox->setChecked(bIsInternal); - m_pFunctionNameLineEdit->setFocus(); - pLabel->setBuddy(m_pInternalCheckBox); - connect(m_pFunctionNameLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged(const QString &))); - - pHBox->setAlignment(m_pInternalCheckBox,Qt::AlignLeft); - pHBox->setStretchFactor(m_pInternalCheckBox,70); - pHBox->setStretchFactor(pLabel,30); - - pHBox = new KviTalHBox(this); - pHBox->setSpacing(0); - pHBox->setMargin(0); - pLayout->addWidget(pHBox,4,0); - - m_pNewFunctionButton = new QPushButton(pHBox); - m_pNewFunctionButton->setObjectName("newfunctionbutton"); - if(!bRenameMode) - m_pNewFunctionButton->setText(__tr2qs_ctx("&Add","editor")); - else - m_pNewFunctionButton->setText(__tr2qs_ctx("&Rename","editor")); - - if(szFunctionName.isEmpty()) - m_pNewFunctionButton->setEnabled(false); - connect(m_pNewFunctionButton, SIGNAL(clicked()), this, SLOT(accept())); - - QPushButton * pCancelButton = new QPushButton(pHBox); - pCancelButton->setObjectName("cancelButton"); - pCancelButton->setText(__tr2qs_ctx("&Cancel","editor")); - connect(pCancelButton, SIGNAL(clicked()), this, SLOT(reject())); - - setLayout(pLayout); -} - -KviClassEditorFunctionDialog::~KviClassEditorFunctionDialog() -{ -} - -void KviClassEditorFunctionDialog::textChanged(const QString & szText) -{ - m_pNewFunctionButton->setEnabled(!szText.isEmpty()); -} diff --git a/src/modules/classeditor/classeditor.h b/src/modules/classeditor/classeditor.h deleted file mode 100644 index c04bd7da4..000000000 --- a/src/modules/classeditor/classeditor.h +++ /dev/null @@ -1,639 +0,0 @@ -#ifndef _CLASSEDITOR_H_ -#define _CLASSEDITOR_H_ -//============================================================================= -// -// File : classeditor.h -// Creation date : Mon Feb 15 2010 14:35:55 CEST by Carbone Alessandro -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2010 Alessandro Carbone (elfonol at gmail dot com) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the linkss of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -/** -* \file classeditor.h -* \author Alessandro Carbone -* \brief Class Editor window -*/ - -#include "KviWindow.h" -#include "KviCString.h" -#include "KviPointerList.h" -#include "KviTalPopupMenu.h" -#include "KviHeapObject.h" -#include "KviKvsObjectClass.h" - -#include -#include -#include -#include -#include -#include - -class QLineEdit; -class QStringList; -class QPushButton; -class QCheckBox; -class QLabel; -class QSplitter; -class KviScriptEditor; - -/** -* \class KviClassEditorTreeWidget -* \brief Describes the tree widget hierarchy -*/ -class KviClassEditorTreeWidget : public QTreeWidget -{ - Q_OBJECT -public: - /** - * \brief Construct the tree widget - * \param pParent The parent widget - * \return KviClassEditorTreeWidget - */ - KviClassEditorTreeWidget(QWidget * pParent); - - /** - * \brief Destroys the tree widget - */ - ~KviClassEditorTreeWidget(); -protected: - virtual void mousePressEvent(QMouseEvent * e); -signals: - /** - * \brief Emitted when we press the mouse right button - * \param pItem The item clicked - * \param pos The position of the cursor - * \return void - */ - void rightButtonPressed(QTreeWidgetItem * pItem, QPoint pos); -}; - -/** -* \class KviClassEditorTreeWidgetItem -* \brief Describes an item inside the class editor tree widget -*/ -class KviClassEditorTreeWidgetItem : public QTreeWidgetItem, public KviHeapObject -{ -public: - /** - * \enum Type - * \brief Contains the type of the class item - */ - enum Type - { - Class, /**< The item is a class */ - Namespace, /**< The item is a namespace */ - Method /**< The item is a member function */ - }; -public: - /** - * \brief Constructs the class editor tree widget item - * \param pTreeWidget The parent tree widget - * \param eType The type of the item - * \param szName The name of the item - * \return KviClassEditorTreeWidgetItem - */ - KviClassEditorTreeWidgetItem(QTreeWidget * pTreeWidget, Type eType, const QString & szName); - - /** - * \brief Constructs the class editor tree widget item - * \param pParentItem The parent tree widget item - * \param eType The type of the item - * \param szName The name of the item - * \return KviClassEditorTreeWidgetItem - */ - KviClassEditorTreeWidgetItem(KviClassEditorTreeWidgetItem * pParentItem, Type eType, const QString & szName); - - /** - * \brief Destroys the class editor tree widget item - */ - ~KviClassEditorTreeWidgetItem(){}; -protected: - Type m_eType; - QString m_szName; - QString m_szBuffer; - QString m_szInheritsClassName; - QString m_szReminder; - bool m_bClassModified; - bool m_bInternal; - int m_iPos; -public: - /** - * \brief Sets the class name on which the class inherits from - * \param szInheritsClassName The parent class name - * \return void - */ - void setInheritsClass(QString szInheritsClassName){ m_szInheritsClassName = szInheritsClassName; }; - - /** - * \brief Returns the class name of the classes we inherit from - * \return QString - */ - QString inheritsClass(){ return m_szInheritsClassName; }; - - /** - * \brief Returns the name of the item - * \return const QString & - */ - const QString & name(){ return m_szName; }; - - /** - * \brief Sets the name of the item - * \param szName The name of the item :P - * \return void - */ - void setName(const QString & szName); - - /** - * \brief Sets the list of parameters the function accept - * \param szRem The parameters' list - * \return void - */ - void setReminder(const QString & szRem){ m_szReminder = szRem; }; - - /** - * \brief Returns the parameters list - * \return QString - */ - QString reminder(){ return m_szReminder; }; - - /** - * \brief Sets the state of the class as non-built - * \param bModified Whether the class is modified - * \return void - */ - void setClassNotBuilt(bool bModified); - - /** - * \brief Returns true if we class is not built yet, false otherwise - * \return bool - */ - bool classNotBuilt(){ return m_bClassModified; }; - - /** - * \brief Sets the function as internal - * \param bInternal Whether the function is internal or not - * \return void - */ - void setInternalFunction(bool bInternal){ m_bInternal = bInternal; }; - - /** - * \brief Returns true if the function is set as internal, false otherwise - * \return bool - */ - bool isInternalFunction(){ return m_bInternal; }; - - /** - * \brief Returns the type of the item - * \return Type - */ - Type type(){ return m_eType; }; - - /** - * \brief Sets the type of the item - * \param eType The type! - * \return void - */ - void setType(Type eType); - - /** - * \brief Returns true if the item is a class, false otherwise - * \return bool - */ - bool isClass(){ return m_eType == Class; }; - - /** - * \brief Returns true if the item is a namespace, false otherwise - * \return bool - */ - bool isNamespace(){ return m_eType == Namespace; }; - - /** - * \brief Returns true if the item is a member function, false otherwise - * \return bool - */ - bool isMethod(){ return m_eType == Method; }; - - /** - * \brief Saves the code of the item in a buffer - * \param szBuffer The buffer ;) - * \return void - */ - void setBuffer(const QString & szBuffer){ m_szBuffer = szBuffer; }; - - /** - * \brief Returns the buffer containing the code of the item - * \return const QString & - */ - const QString & buffer(){ return m_szBuffer; }; - - /** - * \brief Returns the cursor's position - * \return const int & - */ - const int & cursorPosition(){ return m_iPos; }; - - /** - * \brief Sets the cursor position - * \param iPos The position of the cursor - * \return void - */ - void setCursorPosition(const int & iPos){ m_iPos = iPos; }; -}; - -/** -* \class KviClassEditor -* \brief The Class Editor module -*/ -class KviClassEditor : public QWidget -{ - Q_OBJECT -public: - /** - * \brief Constructs the class editor object - * \param pParent The parent widget - * \return KviClassEditor - */ - KviClassEditor(QWidget * pParent); - - /** - * \brief Destroys the class editor object - */ - ~KviClassEditor(); -public: - KviScriptEditor * m_pEditor; - KviClassEditorTreeWidget * m_pTreeWidget; - QLabel * m_pClassNameLabel; - QPushButton * m_pClassNameRenameButton; - QLabel * m_pFunctionNameLabel; - QPushButton * m_pFunctionNameRenameButton; - QLabel * m_pReminderLabel; - - KviClassEditorTreeWidgetItem * m_pLastEditedItem; - KviClassEditorTreeWidgetItem * m_pLastClickedItem; - KviTalPopupMenu * m_pContextPopup; - QSplitter * m_pSplitter; - QString m_szDir; - bool m_bSaving; -protected: - KviPointerHashTable * m_pClasses; -public: - /** - * \brief Called to save the window properties - * \param pCfg The configuration file - * \return void - */ - virtual void saveProperties(KviConfigurationFile * pCfg); - - /** - * \brief Called to load the window properties - * \param pCfg The configuration file - * \return void - */ - virtual void loadProperties(KviConfigurationFile * pCfg); - - /** - * \brief Builds the class! - * \return void - */ - void build(); - - /** - * \brief Saves non-built classes to a file - * \return void - */ - void saveNotBuiltClasses(); - - /** - * \brief Loads non-built classes to a file - * \return void - */ - void loadNotBuiltClasses(); - - /** - * \brief Searches a function - * \param szFunctionName The name of the function - * \param pClass The class in which the function is - * \return KviClassEditorTreeWidgetItem * - */ - KviClassEditorTreeWidgetItem * findFunction(const QString & szFunctionName, KviClassEditorTreeWidgetItem * pClass); - - /** - * \brief Exports class to a file - * \param bSelectedOnly Whether to export only selected files - * \param bSingleFiles Whether to export to single files - * \return void - */ - void exportClasses(bool bSelectedOnly, bool bSingleFiles = false); - - /** - * \brief Exports the current selection to single files - * \param pList The list of file to export - * \return void - */ - void exportSelectionInSinglesFiles(KviPointerList * pList); - - /** - * \brief Removes the item from the tree - * \param pItem The item to remove - * \return void - */ - void cutItem(KviClassEditorTreeWidgetItem * pItem); -protected: - //void recursiveSearchReplace(const QString &szSearch,KviClassEditorTreeWidgetItem * it,bool bReplace=false,const QString &szReplace="n"); - - void exportClassBuffer(QString & szBuffer, KviClassEditorTreeWidgetItem * pItem); - - void oneTimeSetup(); - void createFullClass(KviKvsObjectClass * pClass, KviClassEditorTreeWidgetItem * pItem, const QString & szClassName); - - void saveLastEditedItem(); - void appendSelectedClassItems(KviPointerList * pList); - void appendSelectedClassItemsRecursive(KviPointerList * pList, QTreeWidgetItem * pStartFrom); - - void appendAllClassItems(KviPointerList * pList); - void appendAllClassItemsRecursive(KviPointerList * l,QTreeWidgetItem * pStartFrom); - - void openParentItems(QTreeWidgetItem * pItem); - void activateItem(QTreeWidgetItem * pItem); - bool hasSelectedItems(); - bool askForClassName(QString & szClassName, QString & szInheritsClassName, bool bEdit); - bool askForNamespaceName(const QString & szAction, const QString & szText, const QString & szInitialText, QString & szNameBuffer); - bool askForFunction(QString & szFunctionName, QString & szReminder, bool * pbInternal, const QString & szClassName, bool bRenameMode); - void searchInheritedClasses(const QString szClass, KviPointerList & lInheritsedClasses); - - /** - * \brief Returns true if the class exists, false otherwise - * \param szName The name of the class - * \return bool - */ - bool classExists(QString & szName); - - /** - * \brief Renames a class - * \param pClass The class to rename - * \return void - */ - void renameClass(KviClassEditorTreeWidgetItem * pClass); - - /** - * \brief Renames a namespace - * \param pNamespace The namespace to rename - * \return void - */ - void renameNamespace(KviClassEditorTreeWidgetItem * pNamespace); - - bool removeItem(KviClassEditorTreeWidgetItem * pItem, KviPointerList & lRemovedItems, bool * pbYesToAll); - void updateClassHierarchy(KviClassEditorTreeWidgetItem * pClass); - - void removeItemChildren(KviClassEditorTreeWidgetItem * pItem, KviPointerList & lRemovedItems); - void buildFullItemPath(KviClassEditorTreeWidgetItem * pItem, QString & szBuffer); - QString buildFullClassName(KviClassEditorTreeWidgetItem * pItem); - KviClassEditorTreeWidgetItem * createFullItem(const QString & szFullName); - KviClassEditorTreeWidgetItem * createFullNamespace(const QString & szFullName); - - /** - * \brief Searches an item - * \param szName The name of the item to find - * \return KviClassEditorTreeWidgetItem * - */ - KviClassEditorTreeWidgetItem * findItem(const QString & szName); - - - - KviClassEditorTreeWidgetItem * findTopLevelItem(const QString & szName); - KviClassEditorTreeWidgetItem * createFullItemRecursive(QTreeWidgetItem * pCurrent, QStringList & lNameSpaces, int & iLevel, bool bCreateNameSpace = 0); -protected slots: - void currentItemChanged(QTreeWidgetItem * pItem, QTreeWidgetItem *); - void customContextMenuRequested(QPoint); - void newClass(); - void newNamespace(); - void newMemberFunction(); - void renameFunction(); - KviClassEditorTreeWidgetItem * newItem(QString & szName, KviClassEditorTreeWidgetItem::Type eType); - - void renameItem(); - - void exportAll(); - void exportSelectedSepFiles(); - void exportSelected(); - void slotFind(); - void slotFindWord(const QString &); - void searchReplace(const QString & szSearch, bool bReplace = false, const QString & szReplace = "n"); - - /** - * \brief Called when we collapse an item - * \param pItem The item to collapse - * \return void - */ - void slotCollapseItems(); - - /** - * \brief Called when we collapse an item recursively - * \param pItem The starting item to collapse - * \return void - */ - void recursiveCollapseItems(KviClassEditorTreeWidgetItem * pItem); - - /** - * \brief Called when we want to remove all selected items - * \return void - */ - void removeSelectedItems(); - - /** - * \brief Called when we replace text everywhere - * \param szBefore The text before the replace - * \param szAfter The text after the replace - * \return void - */ - void slotReplaceAll(const QString & szBefore, const QString & szAfter); -}; - -/** -* \class KviClassEditorWindow -* \brief This is the Class Editor window -*/ -class KviClassEditorWindow : public KviWindow -{ - Q_OBJECT -public: - /** - * \brief Constructs the class editor window - * \param pFrm The parent frame - * \return KviClassEditorWindow - */ - KviClassEditorWindow(KviMainWindow * pFrm); - - /** - * \brief Destroys the class editor window - */ - ~KviClassEditorWindow(); -protected: - KviClassEditor * m_pEditor; -protected: - /** - * \brief Returns the class editor small icon - * \return QPixmap * - */ - virtual QPixmap * myIconPtr(); - - /** - * \brief Sets the configuration group name as classeditor - * \param szName The name of the group - * \return void - */ - virtual void configGroupName(QString & szName); - - /** - * \brief Called to save the window properties - * \param pCfg The configuration file - * \return void - */ - virtual void saveProperties(KviConfigurationFile * pCfg); - - /** - * \brief Called to load the window properties - * \param pCfg The configuration file - * \return void - */ - virtual void loadProperties(KviConfigurationFile * pCfg); -protected slots: - /** - * \brief Called when we click the cancel button - * \return void - */ - void cancelClicked(); - - /** - * \brief Called when we want to build the class - * \return void - */ - void buildClicked(); - - /** - * \brief Called when we want to save the class - * \return void - */ - void saveClicked(); -}; - -/** -* \class KviClassEditorDialog -* \brief This class constructs the dialog to create a new class -*/ -class KviClassEditorDialog: public QDialog -{ - Q_OBJECT -public: - /** - * \brief Constructs the class dialog - * \param pParent The parent widget - * \param szName The name of the widget - * \param pClasses The container of all classes of our namespace - * \param szClassName The name of the class - * \param szInheritsClassName The name of the classes in which this inherits from - * \param bRenameMode Whether the dialog is in rename mode - * \return KviClassEditorDialog - */ - KviClassEditorDialog(QWidget * pParent, const QString & szName, KviPointerHashTable * pClasses, const QString & szClassName, const QString & szInheritsClassName, bool bRenameMode = false); - - /** - * \brief Destroys the class dialog - */ - ~KviClassEditorDialog(); -protected: - QPushButton * m_pNewClassButton; - QLineEdit * m_pClassNameLineEdit; - QComboBox * m_pInheritsClassComboBox; -public: - /** - * \brief Returns the class name - * \return QString - */ - QString className(){ return m_pClassNameLineEdit->text(); }; - - /** - * \brief Returns the class name of the parent classes - * \return QString - */ - QString inheritsClassName(){ return m_pInheritsClassComboBox->currentText(); }; -protected slots: - /** - * \brief Triggered when the name of the class change - * \return void - */ - void textChanged(const QString &); -}; - -/** -* \class KviClassEditorFunctionDialog -* \brief This class constructs the dialog to create a new member function -*/ -class KviClassEditorFunctionDialog: public QDialog -{ - Q_OBJECT -public: - /** - * \brief Constructs the function dialog - * \param pParent The parent widget - * \param szName The name of the widget - * \param szClassName The name of the class - * \param szFunctionName The name of the function - * \param szReminder The parameters of the function - * \param bIsInternal Whether the funtion is set as internal - * \param bRenameMode Whether the dialog is in rename mode - * \return KviClassEditorFunctionDialog - */ - KviClassEditorFunctionDialog(QWidget * pParent, const QString & szName, const QString & szClassName, const QString & szFunctionName, const QString & szReminder, bool bIsInternal, bool bRenameMode = false); - - /** - * \brief Destroys the function dialog - */ - ~KviClassEditorFunctionDialog(); -protected: - QPushButton * m_pNewFunctionButton; - QLineEdit * m_pFunctionNameLineEdit; - QLineEdit * m_pReminderLineEdit; - QCheckBox * m_pInternalCheckBox; -public: - /** - * \brief Returns the function name - * \return QString - */ - QString functionName(){ return m_pFunctionNameLineEdit->text(); }; - - /** - * \brief Returns the parameters of the function - * \return QString - */ - QString reminder(){ return m_pReminderLineEdit->text(); }; - - /** - * \brief Returns true if the function is set as internal, false otherwise - * \return bool - */ - bool isInternalFunction(){ return m_pInternalCheckBox->isChecked(); }; -protected slots: - /** - * \brief Triggered when the name of the function change - * \return void - */ - void textChanged(const QString &); -}; -#endif //_CLASSEDITOR_H_ diff --git a/src/modules/classeditor/libkviclasseditor.cpp b/src/modules/classeditor/libkviclasseditor.cpp index a0214b8d8..a45256029 100644 --- a/src/modules/classeditor/libkviclasseditor.cpp +++ b/src/modules/classeditor/libkviclasseditor.cpp @@ -22,14 +22,14 @@ // //============================================================================= -#include "classeditor.h" +#include "ClassEditorWindow.h" #include "KviModule.h" #include "KviLocale.h" #include "KviMainWindow.h" -KviClassEditorWindow * g_pClassEditorWindow = 0; +ClassEditorWindow * g_pClassEditorWindow = 0; KviModule * g_pClassEditorModule = 0; @@ -50,7 +50,7 @@ static bool classeditor_kvs_cmd_open(KviKvsModuleCommandCall * c) { if(!g_pClassEditorWindow) { - g_pClassEditorWindow = new KviClassEditorWindow(c->window()->frame()); + g_pClassEditorWindow = new ClassEditorWindow(c->window()->frame()); c->window()->frame()->addWindow(g_pClassEditorWindow); } diff --git a/src/modules/codetester/CMakeLists.txt b/src/modules/codetester/CMakeLists.txt index 87c4cedca..1cc744655 100644 --- a/src/modules/codetester/CMakeLists.txt +++ b/src/modules/codetester/CMakeLists.txt @@ -1,12 +1,12 @@ # CMakeLists for src/modules/codetester SET(kvicodetester_MOC_HDRS - codetester.h + CodeTesterWindow.h ) SET(kvicodetester_SRCS libkvicodetester.cpp - codetester.cpp + CodeTesterWindow.cpp ) # After this call, files will be moc'ed to moc_kvi_*.cpp diff --git a/src/modules/codetester/CodeTesterWindow.cpp b/src/modules/codetester/CodeTesterWindow.cpp new file mode 100644 index 000000000..f21a610da --- /dev/null +++ b/src/modules/codetester/CodeTesterWindow.cpp @@ -0,0 +1,141 @@ +//============================================================================= +// +// File : CodeTesterWindow.cpp +// Creation date : Mon Dec 23 2002 20:28:18 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the linkss of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "CodeTesterWindow.h" + +#include "KviIconManager.h" +#include "KviOptions.h" +#include "KviLocale.h" +#include "KviConfigurationFile.h" +#include "KviFileDialog.h" +#include "KviFileUtils.h" +#include "KviScriptEditor.h" +#include "KviApplication.h" +#include "KviConsoleWindow.h" +#include "KviParameterList.h" +#include "KviKvsScript.h" +#include "KviKvsVariantList.h" +#include "KviTalPopupMenu.h" + +#include +#include +#include + + +extern KviPointerList * g_pCodeTesterWindowList; + + +CodeTesterWidget::CodeTesterWidget(QWidget * par) +: QWidget(par) +{ + setObjectName("code_tester"); + QGridLayout * g = new QGridLayout(this); + m_pEditor = KviScriptEditor::createInstance(this); + g->addWidget(m_pEditor,0,0,1,4); + //g->addMultiCellWidget(m_pEditor,0,0,0,3); + m_pExecuteButton = new QPushButton(__tr2qs_ctx("&Execute","editor"),this); + g->addWidget(m_pExecuteButton,1,3); + connect(m_pExecuteButton,SIGNAL(clicked()),this,SLOT(execute())); + + m_pModeLabel = new QLabel(__tr2qs_ctx("Params:","editor"),this); + g->addWidget(m_pModeLabel,1,1); + m_pParams = new QLineEdit(this); + g->addWidget(m_pParams,1,2); +} + +CodeTesterWidget::~CodeTesterWidget() +{ + KviScriptEditor::destroyInstance(m_pEditor); +} + +//#warning "Allow to bind the command to a specified window" + +void CodeTesterWidget::execute() +{ + QString parms = m_pParams->text(); + QString buffer; + m_pEditor->getText(buffer); + KviConsoleWindow * con = g_pApp->activeConsole(); + //KviParameterList * l = new KviParameterList(parms.ptr()); + KviKvsScript::run(buffer,con,new KviKvsVariantList(new QString(parms))); +} + +CodeTesterWindow::CodeTesterWindow(KviMainWindow * lpFrm) +: KviWindow(KVI_WINDOW_TYPE_SCRIPTEDITOR,lpFrm,"codetester",0) +{ + g_pCodeTesterWindowList->append(this); + + m_pTester = new CodeTesterWidget(this); +} + +CodeTesterWindow::~CodeTesterWindow() +{ + g_pCodeTesterWindowList->removeRef(this); +} + +QPixmap * CodeTesterWindow::myIconPtr() +{ + return g_pIconManager->getSmallIcon(KVI_SMALLICON_BOMB); +} + +void CodeTesterWindow::resizeEvent(QResizeEvent *) +{ + m_pTester->setGeometry(0,0,width(),height()); +} + +void CodeTesterWindow::fillCaptionBuffers() +{ + m_szPlainTextCaption = __tr2qs_ctx("Script Tester","editor"); +} + +void CodeTesterWindow::getConfigGroupName(QString &szName) +{ + szName = "codetester"; +} + +void CodeTesterWindow::saveProperties(KviConfigurationFile *) //cfg +{ +/* +#ifdef COMPILE_SCRIPTTOOLBAR + cfg->writeEntry("Sizes",m_pEditor->sizes()); + cfg->writeEntry("LastRaw",m_pEditor->lastEditedRaw().ptr()); + //qDebug("LAST EDITED=%s",m_pEditor->lastEditedRaw().ptr()); +#endif // COMPILE_SCRIPTTOOLBAR +*/ +} + +void CodeTesterWindow::loadProperties(KviConfigurationFile *) //cfg +{ +/* +#ifdef COMPILE_SCRIPTTOOLBAR + QValueList def; + def.append(20); + def.append(80); + m_pEditor->setSizes(cfg->readIntListEntry("Sizes",def)); + KviCString tmp = cfg->readEntry("LastRaw",""); + m_pEditor->editRaw(tmp); + //qDebug("LAST EDITED WAS %s",tmp.ptr()); +#endif // COMPILE_SCRIPTTOOLBAR +*/ +} diff --git a/src/modules/codetester/CodeTesterWindow.h b/src/modules/codetester/CodeTesterWindow.h new file mode 100644 index 000000000..eccdd433e --- /dev/null +++ b/src/modules/codetester/CodeTesterWindow.h @@ -0,0 +1,69 @@ +#ifndef _CODETESTER_H_ +#define _CODETESTER_H_ +//============================================================================= +// +// File : EventEditorWindow.h +// Creation date : Mon Dec 23 2002 20:24:55 CEST by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the linkss of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviWindow.h" +#include "KviCString.h" + +#include + +class QPushButton; +class QLabel; +class KviScriptEditor; + + +class CodeTesterWidget : public QWidget +{ + Q_OBJECT +public: + CodeTesterWidget(QWidget * par); + ~CodeTesterWidget(); +private: + KviScriptEditor * m_pEditor; + QLineEdit * m_pParams; + QPushButton * m_pExecuteButton; + QLabel * m_pModeLabel; +private slots: + void execute(); +}; + +class CodeTesterWindow : public KviWindow +{ + Q_OBJECT +public: + CodeTesterWindow(KviMainWindow * lpFrm); + ~CodeTesterWindow(); +protected: + CodeTesterWidget * m_pTester; +protected: + virtual QPixmap * myIconPtr(); + virtual void fillCaptionBuffers(); + virtual void resizeEvent(QResizeEvent *e); + virtual void getConfigGroupName(QString &szName); + virtual void saveProperties(KviConfigurationFile *); + virtual void loadProperties(KviConfigurationFile *); +}; + +#endif //_CODETESTER_H_ diff --git a/src/modules/codetester/codetester.cpp b/src/modules/codetester/codetester.cpp deleted file mode 100644 index 093f85b04..000000000 --- a/src/modules/codetester/codetester.cpp +++ /dev/null @@ -1,141 +0,0 @@ -//============================================================================= -// -// File : codetester.cpp -// Creation date : Mon Dec 23 2002 20:28:18 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the linkss of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "codetester.h" - -#include "KviIconManager.h" -#include "KviOptions.h" -#include "KviLocale.h" -#include "KviConfigurationFile.h" -#include "KviFileDialog.h" -#include "KviFileUtils.h" -#include "KviScriptEditor.h" -#include "KviApplication.h" -#include "KviConsoleWindow.h" -#include "KviParameterList.h" -#include "KviKvsScript.h" -#include "KviKvsVariantList.h" -#include "KviTalPopupMenu.h" - -#include -#include -#include - - -extern KviPointerList * g_pCodeTesterWindowList; - - -KviCodeTester::KviCodeTester(QWidget * par) -: QWidget(par) -{ - setObjectName("code_tester"); - QGridLayout * g = new QGridLayout(this); - m_pEditor = KviScriptEditor::createInstance(this); - g->addWidget(m_pEditor,0,0,1,4); - //g->addMultiCellWidget(m_pEditor,0,0,0,3); - m_pExecuteButton = new QPushButton(__tr2qs_ctx("&Execute","editor"),this); - g->addWidget(m_pExecuteButton,1,3); - connect(m_pExecuteButton,SIGNAL(clicked()),this,SLOT(execute())); - - m_pModeLabel = new QLabel(__tr2qs_ctx("Params:","editor"),this); - g->addWidget(m_pModeLabel,1,1); - m_pParams = new QLineEdit(this); - g->addWidget(m_pParams,1,2); -} - -KviCodeTester::~KviCodeTester() -{ - KviScriptEditor::destroyInstance(m_pEditor); -} - -//#warning "Allow to bind the command to a specified window" - -void KviCodeTester::execute() -{ - QString parms = m_pParams->text(); - QString buffer; - m_pEditor->getText(buffer); - KviConsoleWindow * con = g_pApp->activeConsole(); - //KviParameterList * l = new KviParameterList(parms.ptr()); - KviKvsScript::run(buffer,con,new KviKvsVariantList(new QString(parms))); -} - -KviCodeTesterWindow::KviCodeTesterWindow(KviMainWindow * lpFrm) -: KviWindow(KVI_WINDOW_TYPE_SCRIPTEDITOR,lpFrm,"codetester",0) -{ - g_pCodeTesterWindowList->append(this); - - m_pTester = new KviCodeTester(this); -} - -KviCodeTesterWindow::~KviCodeTesterWindow() -{ - g_pCodeTesterWindowList->removeRef(this); -} - -QPixmap * KviCodeTesterWindow::myIconPtr() -{ - return g_pIconManager->getSmallIcon(KVI_SMALLICON_BOMB); -} - -void KviCodeTesterWindow::resizeEvent(QResizeEvent *) -{ - m_pTester->setGeometry(0,0,width(),height()); -} - -void KviCodeTesterWindow::fillCaptionBuffers() -{ - m_szPlainTextCaption = __tr2qs_ctx("Script Tester","editor"); -} - -void KviCodeTesterWindow::getConfigGroupName(QString &szName) -{ - szName = "codetester"; -} - -void KviCodeTesterWindow::saveProperties(KviConfigurationFile *) //cfg -{ -/* -#ifdef COMPILE_SCRIPTTOOLBAR - cfg->writeEntry("Sizes",m_pEditor->sizes()); - cfg->writeEntry("LastRaw",m_pEditor->lastEditedRaw().ptr()); - //qDebug("LAST EDITED=%s",m_pEditor->lastEditedRaw().ptr()); -#endif // COMPILE_SCRIPTTOOLBAR -*/ -} - -void KviCodeTesterWindow::loadProperties(KviConfigurationFile *) //cfg -{ -/* -#ifdef COMPILE_SCRIPTTOOLBAR - QValueList def; - def.append(20); - def.append(80); - m_pEditor->setSizes(cfg->readIntListEntry("Sizes",def)); - KviCString tmp = cfg->readEntry("LastRaw",""); - m_pEditor->editRaw(tmp); - //qDebug("LAST EDITED WAS %s",tmp.ptr()); -#endif // COMPILE_SCRIPTTOOLBAR -*/ -} diff --git a/src/modules/codetester/codetester.h b/src/modules/codetester/codetester.h deleted file mode 100644 index d54cc96be..000000000 --- a/src/modules/codetester/codetester.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef _CODETESTER_H_ -#define _CODETESTER_H_ -//============================================================================= -// -// File : eventeditor.h -// Creation date : Mon Dec 23 2002 20:24:55 CEST by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the linkss of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "KviWindow.h" -#include "KviCString.h" - -#include - -class QPushButton; -class QLabel; -class KviScriptEditor; - - -class KviCodeTester : public QWidget -{ - Q_OBJECT -public: - KviCodeTester(QWidget * par); - ~KviCodeTester(); -private: - KviScriptEditor * m_pEditor; - QLineEdit * m_pParams; - QPushButton * m_pExecuteButton; - QLabel * m_pModeLabel; -private slots: - void execute(); -}; - -class KviCodeTesterWindow : public KviWindow -{ - Q_OBJECT -public: - KviCodeTesterWindow(KviMainWindow * lpFrm); - ~KviCodeTesterWindow(); -protected: - KviCodeTester * m_pTester; -protected: - virtual QPixmap * myIconPtr(); - virtual void fillCaptionBuffers(); - virtual void resizeEvent(QResizeEvent *e); - virtual void getConfigGroupName(QString &szName); - virtual void saveProperties(KviConfigurationFile *); - virtual void loadProperties(KviConfigurationFile *); -}; - -#endif //_CODETESTER_H_ diff --git a/src/modules/codetester/libkvicodetester.cpp b/src/modules/codetester/libkvicodetester.cpp index 8c38db8ee..c90fcf843 100644 --- a/src/modules/codetester/libkvicodetester.cpp +++ b/src/modules/codetester/libkvicodetester.cpp @@ -22,7 +22,7 @@ // //=============================================================================== -#include "codetester.h" +#include "CodeTesterWindow.h" #include "KviModule.h" #include "KviLocale.h" @@ -30,7 +30,7 @@ #include "KviPointerList.h" -KviPointerList * g_pCodeTesterWindowList = 0; +KviPointerList * g_pCodeTesterWindowList = 0; /* @@ -49,7 +49,7 @@ KviPointerList * g_pCodeTesterWindowList = 0; static bool codetester_kvs_cmd_open(KviKvsModuleCommandCall * c) { - KviCodeTesterWindow * w = new KviCodeTesterWindow(c->window()->frame()); + CodeTesterWindow * w = new CodeTesterWindow(c->window()->frame()); c->window()->frame()->addWindow(w); w->setFocus(); return true; @@ -59,7 +59,7 @@ static bool codetester_module_init(KviModule * m) { KVSM_REGISTER_SIMPLE_COMMAND(m,"open",codetester_kvs_cmd_open); - g_pCodeTesterWindowList = new KviPointerList(); + g_pCodeTesterWindowList = new KviPointerList(); g_pCodeTesterWindowList->setAutoDelete(false); return true; } @@ -71,7 +71,7 @@ static bool codetester_module_can_unload(KviModule *) static bool codetester_module_cleanup(KviModule *) { - while(KviCodeTesterWindow * w = g_pCodeTesterWindowList->first()) + while(CodeTesterWindow * w = g_pCodeTesterWindowList->first()) { w->close(); // deleted path! } diff --git a/src/modules/dcc/CMakeLists.txt b/src/modules/dcc/CMakeLists.txt index c0cd7cef6..60c4d1436 100644 --- a/src/modules/dcc/CMakeLists.txt +++ b/src/modules/dcc/CMakeLists.txt @@ -1,44 +1,44 @@ # CMakeLists for src/modules/dcc SET(kvidcc_MOC_HDRS - broker.h - chat.h - dialogs.h - marshal.h - send.h - voice.h - window.h + DccBroker.h + DccChatWindow.h + DccDialog.h + DccMarshal.h + DccFileTransfer.h + DccVoiceWindow.h + DccWindow.h ) IF(NOT DEFINED COMPILE_DISABLE_DCC_VIDEO) LIST(APPEND kvidcc_MOC_HDRS - video.h + DccVideoWindow.h ) ENDIF() SET(kvidcc_SRCS - adpcmcodec.cpp - broker.cpp - canvas.cpp + DccVoiceAdpcmCodec.cpp + DccBroker.cpp + DccCanvasWindow.cpp canvaswidget.cpp - chat.cpp - codec.cpp - descriptor.cpp - dialogs.cpp - gsmcodec.cpp + DccChatWindow.cpp + DccVoiceCodec.cpp + DccDescriptor.cpp + DccDialog.cpp + DccVoiceGsmCodec.cpp libkvidcc.cpp - marshal.cpp + DccMarshal.cpp requests.cpp - send.cpp - thread.cpp - utils.cpp - voice.cpp - window.cpp + DccFileTransfer.cpp + DccThread.cpp + DccUtils.cpp + DccVoiceWindow.cpp + DccWindow.cpp ) IF(NOT DEFINED COMPILE_DISABLE_DCC_VIDEO) LIST(APPEND kvidcc_SRCS - video.cpp + DccVideoWindow.cpp ) ENDIF() diff --git a/src/modules/dcc/DccBroker.cpp b/src/modules/dcc/DccBroker.cpp new file mode 100644 index 000000000..3f9191f78 --- /dev/null +++ b/src/modules/dcc/DccBroker.cpp @@ -0,0 +1,994 @@ +//============================================================================= +// +// File : DccBroker.cpp +// Creation date : Tue Sep 19 09 2000 10:21:54 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" + +#include "DccBroker.h" +#include "DccDialog.h" +#include "DccChatWindow.h" +#include "DccFileTransfer.h" +#include "DccVoiceWindow.h" + +#ifndef COMPILE_DISABLE_DCC_VIDEO + #include "DccVideoWindow.h" +#endif + +#ifdef COMPILE_DCC_CANVAS + #include "DccCanvasWindow.h" +#endif + +#include "KviApplication.h" +#include "KviMainWindow.h" +#include "KviLocale.h" +#include "KviOptions.h" +#include "KviConsoleWindow.h" +#include "KviFileUtils.h" +#include "kvi_out.h" +#include "KviMediaManager.h" +#include "KviIrcConnection.h" +#include "KviSharedFilesManager.h" + +#include +#include + +// KviApplication.cpp +extern KVIRC_API KviMediaManager * g_pMediaManager; +extern KVIRC_API KviSharedFilesManager * g_pSharedFilesManager; + +//#warning "The broker might lookup the remote host name" + +DccBroker::DccBroker() +: QObject(0) +{ + setObjectName("dcc_broker"); + DccFileTransfer::init(); + + m_pBoxList = new KviPointerList; + m_pBoxList->setAutoDelete(false); + + m_pDccWindowList = new KviPointerList; + m_pDccWindowList->setAutoDelete(false); + + m_pZeroPortTags = new KviPointerHashTable(17); + m_pZeroPortTags->setAutoDelete(true); +} + +DccBroker::~DccBroker() +{ + delete m_pZeroPortTags; + while(m_pBoxList->first())delete m_pBoxList->first(); + delete m_pBoxList; + m_pBoxList = 0; + while(m_pDccWindowList->first())delete m_pDccWindowList->first(); + delete m_pDccWindowList; + DccFileTransfer::done(); +} + + +KviDccZeroPortTag * DccBroker::addZeroPortTag() +{ + static unsigned int g_uNextZeroPortTag = 0; + g_uNextZeroPortTag++; + KviDccZeroPortTag * t = new KviDccZeroPortTag; + t->m_tTimestamp = QDateTime::currentDateTime(); + t->m_szTag.setNum(g_uNextZeroPortTag); + //t->m_szTag.prepend("mIrc-zero-port-"); + t->m_uResumePosition = 0; + // FIXME: we should clear this dict if it grows too high.... + m_pZeroPortTags->insert(t->m_szTag,t); + return t; +} + +KviDccZeroPortTag * DccBroker::findZeroPortTag(const QString &szTag) +{ + KviDccZeroPortTag * t = m_pZeroPortTags->find(szTag); + if(!t)return 0; + if(t->m_tTimestamp.secsTo(QDateTime::currentDateTime()) > 180) + { + // too late man... + m_pZeroPortTags->remove(szTag); + return 0; + } + return t; +} + +void DccBroker::removeZeroPortTag(const QString &szTag) +{ + m_pZeroPortTags->remove(szTag); +} + +unsigned int DccBroker::dccBoxCount() +{ + return m_pBoxList->count(); +} + +void DccBroker::unregisterDccWindow(KviWindow *wnd) +{ + m_pDccWindowList->removeRef(wnd); +} + +void DccBroker::unregisterDccBox(DccDialog * box) +{ + //qDebug("Forgetting box %d",box); + m_pBoxList->removeRef(box); +} + +void DccBroker::cancelDcc(DccDescriptor * dcc) +{ + delete dcc; + dcc = 0; +} + +void DccBroker::cancelDcc(DccDialog *box,DccDescriptor * dcc) +{ + if(box)box->forgetDescriptor(); + delete dcc; + dcc = 0; +} + +/////////////////////////////////////////////////////////////////////////////// +// RSEND +/////////////////////////////////////////////////////////////////////////////// + +void DccBroker::rsendManage(DccDescriptor * dcc) +{ + // We need the filename... + QFileInfo fi(dcc->szLocalFileName); + if(fi.exists())rsendExecute(0,dcc); + else rsendAskForFileName(dcc); +} + +void DccBroker::rsendAskForFileName(DccDescriptor * dcc) +{ + QStringList filenames; + if( + KviFileDialog::askForOpenFileNames(filenames, + __tr2qs_ctx("Choose Files to Send - KVIrc","dcc"),"") + ) { + if(filenames.count() > 0) + { + DccDescriptor * d; + QStringList::Iterator it=filenames.begin(); + while(it != filenames.end()) + { + d = new DccDescriptor(*dcc); + d->szLocalFileName = *(it); + d->szLocalFileName.trimmed(); + ++it; + if(d->szLocalFileName.isEmpty()) + cancelDcc(d); + else + rsendExecute(d); + } + delete dcc; + } + } else { + cancelDcc(dcc); + } +} + +void DccBroker::rsendExecute(DccDescriptor * dcc) +{ + if(!g_pApp->windowExists(dcc->console())) + { + // No way...we NEED the right IRC context... + g_pApp->activeConsole()->output(KVI_OUT_DCCERROR, + __tr2qs_ctx("Can't send DCC %Q request to %Q: IRC connection has been terminated","dcc"), + &(dcc->szType),&(dcc->szNick)); + delete dcc; + return; + } + + // Ok...we need the file to exist + QFileInfo fi(dcc->szLocalFileName); + if(!(fi.exists() && fi.isReadable() && (fi.isFile()) && (fi.size() > 0))) + { + dcc->console()->output(KVI_OUT_DCCERROR,__tr2qs_ctx("Can't open file %Q for reading","dcc"), + &(dcc->szLocalFileName)); + delete dcc; + return; + } + + dcc->szFileName = dcc->szLocalFileName; + dcc->szFileName = QFileInfo(dcc->szFileName).fileName(); + + QString fName = dcc->szFileName; + fName.replace(' ',"\\040"); // be cool :) + + QString szTag; + if(dcc->isZeroPortRequest()) + { + // actually we tagged it as "nonempty" in /dcc.rsend --zero-port + // retag it with something more reasonable + KviDccZeroPortTag * t = addZeroPortTag(); + t->m_uFileSize = fi.size(); + dcc->setZeroPortRequestTag(t->m_szTag.toLatin1()); // latin1() should be ok here + szTag = t->m_szTag; + + // DCC [ST]SEND + dcc->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC %s %s 127.0.0.1 0 %u %s%c", + dcc->console()->connection()->encodeText(dcc->szNick).data(), + 0x01, + dcc->console()->connection()->encodeText(dcc->szType).data(), + dcc->console()->connection()->encodeText(fName).data(), + fi.size(), + dcc->console()->connection()->encodeText(szTag).data(), + 0x01); + } else { + dcc->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC %s %s %u%c", + dcc->console()->connection()->encodeText(dcc->szNick).data(), + 0x01, + dcc->console()->connection()->encodeText(dcc->szType).data(), + dcc->console()->connection()->encodeText(fName).data(), + fi.size(),0x01); + szTag = dcc->szFileName; + } + + // now add a file offer, so he we will accept it automatically + // 120 secs is a reasonable timeout + QString szMask = dcc->szNick; + szMask += "!*@*"; + + g_pSharedFilesManager->addSharedFile(szTag,dcc->szLocalFileName,szMask,120); + + delete dcc; +} + +void DccBroker::rsendExecute(DccDialog * box,DccDescriptor * dcc) +{ + if(box)box->forgetDescriptor(); + rsendExecute(dcc); +} + + +/////////////////////////////////////////////////////////////////////////////// +// DCC CHAT +/////////////////////////////////////////////////////////////////////////////// + +void DccBroker::handleChatRequest(DccDescriptor * dcc) +{ + if(!dcc->bAutoAccept) + { + // FIXME: better message ? Secure Direct Client Connection...eventually + // need confirmation + QString tmp = __tr2qs_ctx( \ + "%1 [%2@%3] requests a " \ + "Direct Client Connection in %4 mode.
", \ + "dcc").arg(dcc->szNick, dcc->szUser, dcc->szHost, dcc->szType); + +#ifdef COMPILE_SSL_SUPPORT + if(dcc->bIsSSL)tmp += __tr2qs_ctx("The connection will be secured using SSL.
","dcc"); +#endif + + if(dcc->isZeroPortRequest()) + { + tmp += __tr2qs_ctx( \ + "You will be the passive side of the connection.
" \ + ,"dcc"); + } else { + tmp += __tr2qs_ctx( \ + "The connection target will be host %1 on port %2
" \ + ,"dcc").arg(dcc->szIp, dcc->szPort); + } + + + QString caption = __tr2qs_ctx("DCC %1 Request - KVIrc","dcc").arg(dcc->szType); + + DccAcceptDialog * box = new DccAcceptDialog(this,dcc,tmp,caption); + + m_pBoxList->append(box); + connect(box,SIGNAL(accepted(DccDialog *,DccDescriptor *)), + this,SLOT(executeChat(DccDialog *,DccDescriptor *))); + connect(box,SIGNAL(rejected(DccDialog *,DccDescriptor *)), + this,SLOT(cancelDcc(DccDialog *,DccDescriptor *))); + box->show(); + } else { + // auto accept + executeChat(0,dcc); + } +} + +void DccBroker::executeChat(DccDialog *box,DccDescriptor * dcc) +{ + if(box)box->forgetDescriptor(); + + if(!g_pApp->windowExists(dcc->console())) + { + // rebind to the first available console.... + dcc->setConsole(g_pApp->activeConsole()); + } + + KviCString szSubProto = dcc->szType; + szSubProto.toLower(); + + QString tmp = QString("dcc: %1 %2@%3:%4").arg(szSubProto.ptr(), dcc->szNick, dcc->szIp, dcc->szPort); + DccChatWindow * chat = new DccChatWindow(dcc->console()->frame(),dcc,tmp.toUtf8().data()); + + bool bMinimized = dcc->bOverrideMinimize ? dcc->bShowMinimized : \ + (KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccChat) || \ + (dcc->bAutoAccept && KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccChatWhenAutoAccepted))); + + dcc->console()->frame()->addWindow(chat,!bMinimized); + if(bMinimized)chat->minimize(); + m_pDccWindowList->append(chat); +} + +/////////////////////////////////////////////////////////////////////////////// +// ACTIVE VOICE +/////////////////////////////////////////////////////////////////////////////// + +void DccBroker::activeVoiceManage(DccDescriptor * dcc) +{ + if(!dcc->bAutoAccept) + { + // need confirmation + QString tmp = __tr2qs_ctx( + "%1 [%2@%3] requests a
" \ + "Direct Client Connection in VOICE mode.
" \ + "The connection target will be host %4 on port %5
" \ + ,"dcc" \ + ).arg(dcc->szNick, dcc->szUser, dcc->szHost, dcc->szIp, dcc->szPort); + + DccAcceptDialog * box = new DccAcceptDialog(this,dcc,tmp,__tr2qs_ctx("DCC VOICE request","dcc")); + m_pBoxList->append(box); + connect(box,SIGNAL(accepted(DccDialog *,DccDescriptor *)), + this,SLOT(activeVoiceExecute(DccDialog *,DccDescriptor *))); + connect(box,SIGNAL(rejected(DccDialog *,DccDescriptor *)), + this,SLOT(cancelDcc(DccDialog *,DccDescriptor *))); + box->show(); + } else { + // auto accept + activeVoiceExecute(0,dcc); + } +} + +void DccBroker::activeVoiceExecute(DccDialog *box,DccDescriptor * dcc) +{ + if(box)box->forgetDescriptor(); + + if(!g_pApp->windowExists(dcc->console())) + { + // rebind to the first available console.... + dcc->setConsole(g_pApp->activeConsole()); + } + + KviCString tmp(KviCString::Format,"dcc: voice %s@%s:%s",dcc->szNick.toUtf8().data(),dcc->szIp.toUtf8().data(),dcc->szPort.toUtf8().data()); + DccVoiceWindow * v = new DccVoiceWindow(dcc->console()->frame(),dcc,tmp.ptr()); + + bool bMinimized = dcc->bOverrideMinimize ? dcc->bShowMinimized : \ + (KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccVoice) || \ + (dcc->bAutoAccept && KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccVoiceWhenAutoAccepted))); + + dcc->console()->frame()->addWindow(v,!bMinimized); + if(bMinimized)v->minimize(); + + m_pDccWindowList->append(v); +} + + +/////////////////////////////////////////////////////////////////////////////// +// PASSIVE VOICE +/////////////////////////////////////////////////////////////////////////////// + +void DccBroker::passiveVoiceExecute(DccDescriptor * dcc) +{ + KviCString tmp(KviCString::Format,"dcc: voice %s@%s:%s",dcc->szNick.toUtf8().data(),dcc->szIp.toUtf8().data(),dcc->szPort.toUtf8().data()); + DccVoiceWindow * v = new DccVoiceWindow(dcc->console()->frame(),dcc,tmp.ptr()); + //#warning "Create minimized dcc voice ?... or maybe it's too much ? :)" + bool bMinimized = dcc->bOverrideMinimize ? dcc->bShowMinimized : KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccChat); + dcc->console()->frame()->addWindow(v,!bMinimized); + if(bMinimized)v->minimize(); + m_pDccWindowList->append(v); +} + + +/////////////////////////////////////////////////////////////////////////////// +// ACTIVE VIDEO +/////////////////////////////////////////////////////////////////////////////// + +#ifndef COMPILE_DISABLE_DCC_VIDEO +void DccBroker::activeVideoManage(DccDescriptor * dcc) +{ + if(!dcc->bAutoAccept) + { + // need confirmation + QString tmp = __tr2qs_ctx( + "%1 [%2@%3] requests a
" \ + "Direct Client Connection in VIDEO mode.
" \ + "The connection target will be host %4 on port %5
" \ + ,"dcc" \ + ).arg(dcc->szNick, dcc->szUser, dcc->szHost, dcc->szIp, dcc->szPort); + + DccAcceptDialog * box = new DccAcceptDialog(this,dcc,tmp,__tr2qs_ctx("DCC VIDEO request","dcc")); + m_pBoxList->append(box); + connect(box,SIGNAL(accepted(DccDialog *,DccDescriptor *)), + this,SLOT(activeVideoExecute(DccDialog *,DccDescriptor *))); + connect(box,SIGNAL(rejected(DccDialog *,DccDescriptor *)), + this,SLOT(cancelDcc(DccDialog *,DccDescriptor *))); + box->show(); + } else { + // auto accept + activeVideoExecute(0,dcc); + } +} + +void DccBroker::activeVideoExecute(DccDialog *box,DccDescriptor * dcc) +{ + if(box)box->forgetDescriptor(); + + if(!g_pApp->windowExists(dcc->console())) + { + // rebind to the first available console.... + dcc->setConsole(g_pApp->activeConsole()); + } + + KviCString tmp(KviCString::Format,"dcc: video %s@%s:%s",dcc->szNick.toUtf8().data(),dcc->szIp.toUtf8().data(),dcc->szPort.toUtf8().data()); + DccVideoWindow * v = new DccVideoWindow(dcc->console()->frame(),dcc,tmp.ptr()); + + bool bMinimized = dcc->bOverrideMinimize ? dcc->bShowMinimized : \ + (KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccVideo) || \ + (dcc->bAutoAccept && KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccVideoWhenAutoAccepted))); + + dcc->console()->frame()->addWindow(v,!bMinimized); + if(bMinimized)v->minimize(); + + m_pDccWindowList->append(v); +#else +void DccBroker::activeVideoExecute(DccDialog *,DccDescriptor *) +{ +#endif +} + + +/////////////////////////////////////////////////////////////////////////////// +// PASSIVE VIDEO +/////////////////////////////////////////////////////////////////////////////// + +#ifndef COMPILE_DISABLE_DCC_VIDEO +void DccBroker::passiveVideoExecute(DccDescriptor * dcc) +{ + KviCString tmp(KviCString::Format,"dcc: video %s@%s:%s",dcc->szNick.toUtf8().data(),dcc->szIp.toUtf8().data(),dcc->szPort.toUtf8().data()); + DccVideoWindow * v = new DccVideoWindow(dcc->console()->frame(),dcc,tmp.ptr()); + //#warning "Create minimized dcc video ?... or maybe it's too much ? :)" + bool bMinimized = dcc->bOverrideMinimize ? dcc->bShowMinimized : KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccChat); + dcc->console()->frame()->addWindow(v,!bMinimized); + if(bMinimized)v->minimize(); + m_pDccWindowList->append(v); +#else +void DccBroker::passiveVideoExecute(DccDescriptor *) +{ +#endif +} + + +/////////////////////////////////////////////////////////////////////////////// +// ACTIVE CANVAS +/////////////////////////////////////////////////////////////////////////////// + +#ifdef COMPILE_DCC_CANVAS +void DccBroker::activeCanvasManage(DccDescriptor * dcc) +{ + if(!dcc->bAutoAccept) + { + // need confirmation + QString tmp = __tr2qs_ctx( \ + "%1 [%2@%3] requests a
" \ + "Direct Client Connection in CANVAS mode.
" \ + "The connection target will be host %4 on port %5
" \ + ,"dcc" \ + ).arg(dcc->szNick, dcc->szUser, dcc->szHost, dcc->szIp, dcc->szPort); + + DccAcceptDialog * box = new DccAcceptDialog(this,dcc,tmp,__tr2qs_ctx("DCC CANVAS request","dcc")); + m_pBoxList->append(box); + connect(box,SIGNAL(accepted(DccDialog *,DccDescriptor *)), + this,SLOT(activeCanvasExecute(DccDialog *,DccDescriptor *))); + connect(box,SIGNAL(rejected(DccDialog *,DccDescriptor *)), + this,SLOT(cancelDcc(DccDialog *,DccDescriptor *))); + box->show(); + } else { + // auto accept + activeCanvasExecute(0,dcc); + } +} +#endif + +#ifdef COMPILE_DCC_CANVAS +void DccBroker::activeCanvasExecute(DccDialog *box,DccDescriptor * dcc) +{ + if(box)box->forgetDescriptor(); + + if(!g_pApp->windowExists(dcc->console())) + { + // rebind to the first available console.... + dcc->setConsole(g_pApp->activeConsole()); + } + + KviCString tmp(KviCString::Format,"dcc: canvas %s@%s:%s",dcc->szNick.toUtf8().data(),dcc->szIp.toUtf8().data(),dcc->szPort.toUtf8().data()); + DccCanvasWindow * cnv = new DccCanvasWindow(dcc->console()->frame(),dcc,tmp.ptr()); + + //#warning "This option should be dedicated to Dcc Canvas!....for now we are using the DccChat options" + bool bMinimized = dcc->bOverrideMinimize ? dcc->bShowMinimized : \ + (KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccChat) || \ + (dcc->bAutoAccept && KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccChatWhenAutoAccepted))); + + dcc->console()->frame()->addWindow(cnv,!bMinimized); + if(bMinimized)cnv->minimize(); + + m_pDccWindowList->append(cnv); +#else +void DccBroker::activeCanvasExecute(DccDialog *,DccDescriptor *) +{ +#endif +} + +/////////////////////////////////////////////////////////////////////////////// +// PASSIVE CANVAS +/////////////////////////////////////////////////////////////////////////////// +#ifdef COMPILE_DCC_CANVAS +void DccBroker::passiveCanvasExecute(DccDescriptor * dcc) +{ + KviCString tmp(KviCString::Format,"dcc: canvas %s@%s:%s",dcc->szNick.toUtf8().data(),dcc->szIp.toUtf8().data(),dcc->szPort.toUtf8().data()); + DccCanvasWindow * cnv = new DccCanvasWindow(dcc->console()->frame(),dcc,tmp.ptr()); + //#warning "This option should be dedicated to Dcc Canvas!....for now we are using the DccChat options" + bool bMinimized = dcc->bOverrideMinimize ? dcc->bShowMinimized : KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccChat); + dcc->console()->frame()->addWindow(cnv,!bMinimized); + if(bMinimized)cnv->minimize(); + m_pDccWindowList->append(cnv); +} +#endif + +/////////////////////////////////////////////////////////////////////////////// +// SEND +/////////////////////////////////////////////////////////////////////////////// + +void DccBroker::recvFileManage(DccDescriptor * dcc) +{ + if(dcc->bIsIncomingAvatar) + { + bool bOk; + quint64 size = dcc->szFileSize.toULongLong(&bOk); + if(bOk) { + if(size>=KVI_OPTION_UINT(KviOption_uintMaximumRequestedAvatarSize)) { + cancelDcc(0,dcc); + return; + } + } + } + + if(!dcc->bAutoAccept) + { + // need confirmation + QString tmp; + + if(dcc->bActive) + { + // Normal active send: we will be connecting + tmp = __tr2qs_ctx( \ + "%1 [%2@%3] " \ + "wants to send you the file " \ + "'%4', " \ + "%5 large.
" \ + "The connection target will be host %6 on port %7
" \ + ,"dcc" \ + ).arg(dcc->szNick, dcc->szUser, dcc->szHost, dcc->szFileName, + KviQString::makeSizeReadable(dcc->szFileSize.toULongLong()), + dcc->szIp, dcc->szPort); + + } else { + // passive: we will be listening! + tmp = __tr2qs_ctx( \ + "%1 [%2@%3] " + "wants to send you the file " \ + "'%4', " \ + "%5 large.
" \ + "You will be the passive side of the connection.
" \ + ,"dcc" \ + ).arg(dcc->szNick, dcc->szUser, dcc->szHost, dcc->szFileName, + KviQString::makeSizeReadable(dcc->szFileSize.toULongLong())); + } + + if(dcc->bIsIncomingAvatar) + { + tmp += __tr2qs_ctx( \ + "

Note:
" \ + "The file appears to be an avatar that you have requested. " \ + "You should not change its filename. " \ + "Save it in a location where KVIrc can find it, such as " \ + "the 'avatars', 'incoming', or 'pics' directories, " \ + "your home directory, or the save directory for the incoming file type. " \ + "The default save path will probably work. " \ + "You can instruct KVIrc to accept incoming avatars automatically " \ + "by setting the option boolAutoAcceptIncomingAvatars to true.
" \ + ,"dcc" \ + ); + } + + //#warning "Maybe remove the pending avatar if rejected ?" + + QString title = __tr2qs_ctx("DCC %1 Request - KVIrc","dcc").arg(dcc->szType); + + DccAcceptDialog * box = new DccAcceptDialog(this,dcc,tmp,title); + m_pBoxList->append(box); + connect(box,SIGNAL(accepted(DccDialog *,DccDescriptor *)), + this,SLOT(chooseSaveFileName(DccDialog *,DccDescriptor *))); + connect(box,SIGNAL(rejected(DccDialog *,DccDescriptor *)), + this,SLOT(cancelDcc(DccDialog *,DccDescriptor *))); + box->show(); + } else { + // auto accept + if(_OUTPUT_VERBOSE) + { + dcc->console()->output(KVI_OUT_DCCMSG,__tr2qs_ctx("Auto-accepting DCC %Q request from %Q!%Q@%Q for file %Q","dcc"), + &(dcc->szType),&(dcc->szNick),&(dcc->szUser), + &(dcc->szHost),&(dcc->szFileName)); + } + chooseSaveFileName(0,dcc); + } +} + +void DccBroker::chooseSaveFileName(DccDialog *box,DccDescriptor *dcc) +{ + if(box)box->forgetDescriptor(); + + // Lookup the suggested save directory + + dcc->szLocalFileName = ""; + + if(dcc->bIsIncomingAvatar)g_pApp->getLocalKvircDirectory(dcc->szLocalFileName,KviApplication::Avatars); + else { + + if(KVI_OPTION_BOOL(KviOption_boolUseIncomingDccMediaTypeSavePath)) + { + g_pMediaManager->lock(); + if(KviMediaType * mt = g_pMediaManager->findMediaType(dcc->szFileName.toUtf8().data(),false)) + { + if(mt->szSavePath.hasData()) + { + if(KviFileUtils::directoryExists(mt->szSavePath.ptr()))dcc->szLocalFileName = mt->szSavePath; + else { + if(KviFileUtils::makeDir(mt->szSavePath.ptr()))dcc->szLocalFileName = mt->szSavePath; + } + if(KVI_OPTION_BOOL(KviOption_boolSortReceivedByDccFilesByNicks)) + { + KviQString::ensureLastCharIs(dcc->szLocalFileName,KVI_PATH_SEPARATOR_CHAR); + QString cleanNick = dcc->szNick; + KviFileUtils::cleanFileName(cleanNick); + dcc->szLocalFileName.append(cleanNick); + KviFileUtils::adjustFilePath(dcc->szLocalFileName); + } + KviFileUtils::makeDir(dcc->szLocalFileName); + } + } + g_pMediaManager->unlock(); + } + + if(dcc->szLocalFileName.isEmpty()) + { + g_pApp->getLocalKvircDirectory(dcc->szLocalFileName,KviApplication::Incoming); + if(KVI_OPTION_BOOL(KviOption_boolSortReceivedByDccFilesByNicks)) + { + KviQString::ensureLastCharIs(dcc->szLocalFileName,KVI_PATH_SEPARATOR_CHAR); + QString cleanNick = dcc->szNick; + KviFileUtils::cleanFileName(cleanNick); + dcc->szLocalFileName.append(cleanNick); + KviFileUtils::adjustFilePath(dcc->szLocalFileName); + KviFileUtils::makeDir(dcc->szLocalFileName); + } + } + } + KviFileUtils::adjustFilePath(dcc->szLocalFileName); + KviQString::ensureLastCharIs(dcc->szLocalFileName,KVI_PATH_SEPARATOR_CHAR); + + if(!(dcc->bAutoAccept)) + { + QString cleanFilename = dcc->szFileName; + KviFileUtils::cleanFileName(cleanFilename); + dcc->szLocalFileName.append(cleanFilename); + if(KviFileDialog::askForSaveFileName(dcc->szLocalFileName, + __tr2qs_ctx("Choose Files to Save - KVIrc","dcc"),dcc->szLocalFileName)) + { + renameOverwriteResume(0,dcc); + } else { + cancelDcc(dcc); + } + } else { + // auto accept + // WE choose the filename + QString cleanFilename = dcc->szFileName; + KviFileUtils::cleanFileName(cleanFilename); + dcc->szLocalFileName.append(cleanFilename); + + if(_OUTPUT_VERBOSE) + { + dcc->console()->output(KVI_OUT_DCCMSG,__tr2qs_ctx("Auto-saving DCC %Q file %Q as \r![!dbl]play $0\r%Q\r","dcc"), + &(dcc->szType),&(dcc->szFileName),&(dcc->szLocalFileName)); + } + + renameOverwriteResume(0,dcc); + } +} + +void DccBroker::renameOverwriteResume(DccDialog *box,DccDescriptor * dcc) +{ + if(box)box->forgetDescriptor(); + + // Check if file exists + QFileInfo fi(dcc->szLocalFileName); + if(fi.exists() && (fi.size() > 0)) // 0 byte files are senseless for us + { + dcc->szLocalFileSize.setNum(fi.size()); + + bool bOk; + quint64 iRemoteSize = dcc->szFileSize.toULongLong(&bOk); + if(!bOk) + iRemoteSize = 0; + + if(!dcc->bAutoAccept) + { + QString tmp; + bool bDisableResume = false; + + if( + (!bOk) || // remote size is unknown + (iRemoteSize > (quint64)fi.size()) // or it is larger than the actual size on disk + ) + { + tmp = __tr2qs_ctx( \ + "The file '%1' already exists " \ + "and is %2 large.
" \ + "Do you wish to
" \ + "auto-rename the new file,
" \ + "overwrite the existing file, or
" \ + "resume an incomplete download?" \ + ,"dcc" \ + ).arg(dcc->szLocalFileName, KviQString::makeSizeReadable(fi.size())); + } else { + bDisableResume = true; + // the file on disk is larger or equal to the remote one + tmp = __tr2qs_ctx( \ + "The file '%1' already exists " \ + "and is larger than the offered one.
" \ + "Do you wish to
" \ + "auto-rename the new file, or
" \ + "overwrite the existing file ?" \ + ,"dcc" \ + ).arg(dcc->szLocalFileName); + } + + DccRenameDialog * box = new DccRenameDialog(this,dcc,tmp,bDisableResume); + m_pBoxList->append(box); + connect(box,SIGNAL(renameSelected(DccDialog *,DccDescriptor *)), + this,SLOT(renameDccSendFile(DccDialog *,DccDescriptor *))); + connect(box,SIGNAL(overwriteSelected(DccDialog *,DccDescriptor *)), + this,SLOT(recvFileExecute(DccDialog *,DccDescriptor *))); + connect(box,SIGNAL(cancelSelected(DccDialog *,DccDescriptor *)), + this,SLOT(cancelDcc(DccDialog *,DccDescriptor *))); + box->show(); + return; + } + + // auto resume ? + if( + KVI_OPTION_BOOL(KviOption_boolAutoResumeDccSendWhenAutoAccepted) && + (bOk) && // only if the remote size is really known + (iRemoteSize > (quint64)fi.size()) && // only if the remote size is larger than the local size + (!DccFileTransfer::nonFailedTransferWithLocalFileName(dcc->szLocalFileName)) // only if there is no transfer with this local file name yet + ) + { + // yep, auto resume... + dcc->bResume = true; + recvFileExecute(0,dcc); + } else if(iRemoteSize == (quint64)fi.size()) + { + dcc->console()->output(KVI_OUT_DCCMSG,"Transfer aborted: file %Q already completed",&(dcc->szLocalFileName)); + cancelDcc(0,dcc); + } else { + // otherwise auto rename + renameDccSendFile(0,dcc); + } + return; + } + + dcc->szLocalFileSize = "0"; + + // everything OK + recvFileExecute(0,dcc); +} + +void DccBroker::renameDccSendFile(DccDialog *box,DccDescriptor * dcc) +{ + if(box)box->forgetDescriptor(); + + + if(QFileInfo(dcc->szLocalFileName).exists()) + { + KviCString szOrig = dcc->szLocalFileName; + int i = 1; + do { + KviCString szNum; + szNum.setNum(i); + int idx = szOrig.findLastIdx('.'); + if(idx != -1) + { + dcc->szLocalFileName = szOrig.left(idx); + dcc->szLocalFileName += "."; + dcc->szLocalFileName += szNum; + dcc->szLocalFileName += szOrig.right(szOrig.len() - idx); + } else { + dcc->szLocalFileName = szOrig; + dcc->szLocalFileName += "."; + dcc->szLocalFileName += szNum; + } + i++; + } while(QFileInfo(dcc->szLocalFileName).exists()); + + if(_OUTPUT_VERBOSE) + { + dcc->console()->output(KVI_OUT_DCCMSG,__tr2qs_ctx("File %s exists, auto-renaming to %Q","dcc"), + szOrig.ptr(),&(dcc->szLocalFileName)); + } + } + + dcc->szLocalFileSize = "0"; // 0 for sure + + recvFileExecute(0,dcc); +} + +void DccBroker::recvFileExecute(DccDialog *box,DccDescriptor * dcc) +{ + if(box)box->forgetDescriptor(); + + if(!g_pApp->windowExists(dcc->console())) + { + // rebind to the first available console.... + dcc->setConsole(g_pApp->activeConsole()); + } + + //KviDccSend * send = new KviDccSend(dcc->console()->frame(),dcc,tmp.ptr()); + DccFileTransfer * send = new DccFileTransfer(dcc); + + bool bMinimized = dcc->bOverrideMinimize ? dcc->bShowMinimized : \ + (KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccSend) || \ + (dcc->bAutoAccept && KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccSendWhenAutoAccepted))); + + send->invokeTransferWindow(dcc->console(),bMinimized,bMinimized); +} + + +void DccBroker::sendFileManage(DccDescriptor * dcc) +{ + QStringList filenames; + if(KviFileDialog::askForOpenFileNames(filenames,__tr2qs_ctx("Choose Files to Send - KVIrc","dcc"),"")) + { + if(filenames.count() > 0) + { + DccDescriptor * d; + QStringList::Iterator it=filenames.begin(); + while(it != filenames.end()) + { + d = new DccDescriptor(*dcc); + d->szLocalFileName = *(it); + d->szLocalFileName.trimmed(); + ++it; + if(d->szLocalFileName.isEmpty()) + cancelDcc(d); + else + sendFileExecute(0,d); + } + delete dcc; + } + } else { + cancelDcc(dcc); + } +} + +void DccBroker::sendFileExecute(DccDialog * box,DccDescriptor *dcc) +{ + if(box)box->forgetDescriptor(); + + if(!g_pApp->windowExists(dcc->console())) + { + // rebind to the first available console.... + dcc->setConsole(g_pApp->activeConsole()); + } + + QFileInfo fi(dcc->szLocalFileName); + if(!(fi.exists() && fi.isReadable() && (fi.isFile()) && (fi.size() > 0))) + { + dcc->console()->output(KVI_OUT_DCCERROR,__tr2qs_ctx("Can't open file %Q for reading","dcc"), + &(dcc->szLocalFileName)); + delete dcc; + return; + } + + dcc->szFileName = dcc->szLocalFileName; + dcc->szFileName = QFileInfo(dcc->szFileName).fileName(); + + dcc->szLocalFileSize.setNum(fi.size()); + + DccFileTransfer * send = new DccFileTransfer(dcc); + + bool bMinimized = dcc->bOverrideMinimize ? dcc->bShowMinimized : KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccSend); + + send->invokeTransferWindow(dcc->console(),bMinimized,bMinimized); +} + +bool DccBroker::canUnload() +{ + if(m_pBoxList) + { + if((m_pBoxList->count() != 0) || + (m_pDccWindowList->count() != 0) || + (DccFileTransfer::transferCount() != 0))return false; + } // else in the destructor anyway (going to die) + return true; +} + +bool DccBroker::handleResumeAccepted(const char * filename,const char * port,const char * szZeroPortTag) +{ + return DccFileTransfer::handleResumeAccepted(filename,port,szZeroPortTag); +} + +bool DccBroker::handleResumeRequest(KviDccRequest * dcc,const char * filename,const char * port,unsigned long filePos,const char * szZeroPortTag) +{ + //qDebug("HANDLE %s %s %u %s",filename,port,filePos,szZeroPortTag); + // the zeroPOrtTag is nonempty here only if port == 0 + if(kvi_strEqualCI("0",port) && szZeroPortTag) + { + // zero port resume request (we have sent out a DCC SEND 0 + KviDccZeroPortTag * t = findZeroPortTag(QString(szZeroPortTag)); + if(t) + { + // valid zero port resume request + if(filePos >= t->m_uFileSize) + return false; // invalid resume size + + // ok! + t->m_uResumePosition = filePos; + + KviCString szBuffy; + KviIrcServerParser::encodeCtcpParameter(filename,szBuffy); + + dcc->ctcpMsg->msg->console()->connection()->sendFmtData( + "PRIVMSG %s :%cDCC ACCEPT %s %s %u %s%c", + dcc->ctcpMsg->msg->console()->connection()->encodeText(dcc->ctcpMsg->pSource->nick()).data(), + 0x01, + szBuffy.ptr(), + port, + filePos, + szZeroPortTag, + 0x01 + ); + + return true; + } + } + //qDebug("NOT A ZeRO PORT"); + + return DccFileTransfer::handleResumeRequest(filename,port,filePos); +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_DccBroker.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/dcc/DccBroker.h b/src/modules/dcc/DccBroker.h new file mode 100644 index 000000000..6aefcea5b --- /dev/null +++ b/src/modules/dcc/DccBroker.h @@ -0,0 +1,123 @@ +#ifndef _BROKER_H_ +#define _BROKER_H_ +//============================================================================= +// +// File : DccBroker.h +// Creation date : Tue Sep 19 09 2000 10:20:01 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "DccDescriptor.h" + +#include "kvi_settings.h" +#include "KviCString.h" +#include "KviPointerList.h" +#include "KviIrcServerParser.h" +#include "KviPointerHashTable.h" + +#include +#include + +class KviConsoleWindow; +class DccBroker; +class KviWindow; +class DccDialog; + +// #define COMPILE_DCC_CANVAS + + +class KviDccZeroPortTag +{ +public: + QDateTime m_tTimestamp; + QString m_szTag; + unsigned long m_uFileSize; // outgoing file size, valid only for file transfers obviously + unsigned long m_uResumePosition; // if 0 = no resume, valid only for file transfers obviously +}; + +class DccBroker : public QObject +{ + Q_OBJECT +public: + DccBroker(); + ~DccBroker(); +protected: + KviPointerList * m_pBoxList; + KviPointerList * m_pDccWindowList; + KviPointerHashTable * m_pZeroPortTags; +public: + KviDccZeroPortTag * addZeroPortTag(); + KviDccZeroPortTag * findZeroPortTag(const QString &szTag); + void removeZeroPortTag(const QString &szTag); + + unsigned int dccWindowsCount(){ return m_pDccWindowList->count(); }; + unsigned int dccBoxCount(); + + void unregisterDccBox(DccDialog * box); + void unregisterDccWindow(KviWindow *dcc); + + void rsendManage(DccDescriptor * dcc); + void rsendAskForFileName(DccDescriptor * dcc); + + void handleChatRequest(DccDescriptor * dcc); + +#ifdef COMPILE_DCC_CANVAS + void activeCanvasManage(DccDescriptor * dcc); + void passiveCanvasExecute(DccDescriptor * dcc); +#endif + + void activeVoiceManage(DccDescriptor * dcc); + void passiveVoiceExecute(DccDescriptor * dcc); + + void activeVideoManage(DccDescriptor * dcc); + void passiveVideoExecute(DccDescriptor * dcc); + + void recvFileManage(DccDescriptor * dcc); + void sendFileManage(DccDescriptor * dcc); + + bool handleResumeAccepted(const char * filename,const char * port,const char * szZeroPortTag); + bool handleResumeRequest(KviDccRequest * dcc,const char * filename,const char * port,unsigned long filePos,const char * szZeroPortTag); + +public slots: + void rsendExecute(DccDialog * box,DccDescriptor * dcc); + void rsendExecute(DccDescriptor * dcc); + +// void activeChatExecute(DccDialog * box,DccDescriptor * dcc); + void executeChat(DccDialog * box,DccDescriptor * dcc); + + void activeCanvasExecute(DccDialog * box,DccDescriptor * dcc); + void activeVoiceExecute(DccDialog * box,DccDescriptor * dcc); + void activeVideoExecute(DccDialog * box,DccDescriptor * dcc); + + void sendFileExecute(DccDialog * box,DccDescriptor * dcc); + void recvFileExecute(DccDialog * box,DccDescriptor * dcc); + + void chooseSaveFileName(DccDialog *box,DccDescriptor * dcc); + void renameOverwriteResume(DccDialog *box,DccDescriptor * dcc); + void renameDccSendFile(DccDialog *box,DccDescriptor * dcc); + + void cancelDcc(DccDialog *box,DccDescriptor * dcc); + void cancelDcc(DccDescriptor * dcc); + +public: + bool canUnload(); +}; + +#endif diff --git a/src/modules/dcc/DccCanvasWindow.cpp b/src/modules/dcc/DccCanvasWindow.cpp new file mode 100644 index 000000000..73f442b2c --- /dev/null +++ b/src/modules/dcc/DccCanvasWindow.cpp @@ -0,0 +1,301 @@ +//============================================================================= +// +// File : DccCanvasWindow.cpp +// Creation date : Sun Jul 29 07 2001 20:23:13 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#define QT_MODULE_CANVAS + +#include "DccCanvasWindow.h" + +#ifdef COMPILE_DCC_CANVAS + + #include "DccDialog.h" + #include "DccMarshal.h" + #include "canvaswidget.h" + + #define _KVI_DEBUG_CHECK_RANGE_ + #include "kvi_debug.h" + #include "KviOptions.h" + #include "KviInput.h" + #include "KviIrcView.h" + #include "KviIconManager.h" + #include "KviLocale.h" + #include "KviError.h" + #include "kvi_out.h" + #include "KviNetUtils.h" + #include "KviConsoleWindow.h" + #include "KviMainWindow.h" + #include "KviMemory.h" + #include "KviMemory.h" + #include "KviThread.h" + #include "KviIrcSocket.h" + #include "kvi_settings.h" + #include "KviIrcConnection.h" + + #include + + extern DccBroker * g_pDccBroker; + + + DccCanvasWindow::DccCanvasWindow(KviMainWindow *pFrm,DccDescriptor * dcc,const char * name) + : DccWindow(KVI_WINDOW_TYPE_DCCCANVAS,pFrm,name,dcc) + { + m_pSplitter = new QSplitter(QSplitter::Vertical,this,"splitter"); + + m_pCanvas = new DccCanvasWidget(m_pSplitter); + + m_pIrcView = new KviIrcView(m_pSplitter,pFrm,this); + m_pInput = new KviInput(this); + + // setFocusHandler(m_pInput,this); + + m_pMarshal = new DccMarshal(this); + connect(m_pMarshal,SIGNAL(error(int)),this,SLOT(handleMarshalError(int))); + connect(m_pMarshal,SIGNAL(connected()),this,SLOT(connected())); + + + if(!(m_pDescriptor->bActive)) + { + // PASSIVE CONNECTION + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Attempting a passive DCC CANVAS connection","dcc")); + int ret = m_pMarshal->dccListen(dcc->szListenIp,dcc->szListenPort,m_pDescriptor->bDoTimeout); + if(ret != KviError_success)handleMarshalError(ret); + else { + + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Listening on interface %Q port %Q","dcc"), + &(m_pMarshal->localIp()),&(m_pMarshal->localPort())); + + if(dcc->bSendRequest) + { + QString ip = !dcc->szFakeIp.isEmpty() ? dcc->szFakeIp : dcc->szListenIp; + QString port = !dcc->szFakePort.isEmpty() ? dcc->szFakePort.toUtf8().data() : m_pMarshal->localPort(); + //#warning "OPTION FOR SENDING 127.0.0.1 and so on (not an unsigned number)" + struct in_addr a; + if(kvi_stringIpToBinaryIp(ip.toUtf8().data(),&a))ip.setNum(htonl(a.s_addr)); + dcc->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC CANVAS chat %Q %Q%c", + dcc->console()->connection()->encodeText( dcc->szNick.toUtf8().data() ).data(), + 0x01,&ip, + &port, + 0x01); + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Sent DCC CANVAS request to %Q, waiting for the remote client to connect...","dcc"), + &(dcc->szNick)); + } else outputNoFmt(KVI_OUT_DCCMSG,__tr2qs_ctx("DCC CANVAS request not sent: awaiting manual connections","dcc")); + } + } else { + // ACTIVE CONNECTION + outputNoFmt(KVI_OUT_DCCMSG,__tr2qs_ctx("Attempting an active DCC CANVAS connection","dcc")); + int ret = m_pMarshal->dccConnect(dcc->szIp.toUtf8().data(),dcc->szPort.toUtf8().data(),m_pDescriptor->bDoTimeout); + if(ret != KviError_success)handleMarshalError(ret); + else output(KVI_OUT_DCCMSG,__tr2qs_ctx("Contacting host %Q on port %Q","dcc"),&(dcc->szIp),&(dcc->szPort)); + } + + // m_pSlaveThread = 0; + } + + DccCanvasWindow::~DccCanvasWindow() + { + g_pDccBroker->unregisterDccWindow(this); + // if(m_pSlaveThread) + // { + // m_pSlaveThread->terminate(); + // delete m_pSlaveThread; + // m_pSlaveThread = 0; + // } + KviThreadManager::killPendingEvents(this); + // delete m_pDescriptor; + // delete m_pMarshal; + } + + const QString & DccCanvasWindow::target() + { + // This may change on the fly... + m_szTarget.sprintf("%s@%s:%s", + m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data()); + return m_szTarget; + } + + void DccCanvasWindow::fillCaptionBuffers() + { + KviCString tmp(KviCString::Format,"DCC Canvas %s@%s:%s", + m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data()); + + m_szPlainTextCaption = tmp; + + m_szHtmlActiveCaption.sprintf("%s", + KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name().ascii(),tmp.ptr()); + m_szHtmlInactiveCaption.sprintf("%s", + KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name().ascii(),tmp.ptr()); + } + + QPixmap * DccCanvasWindow::myIconPtr() + { + return g_pIconManager->getSmallIcon(KVI_SMALLICON_CANVAS); + } + + void DccCanvasWindow::getBaseLogFileName(KviCString &buffer) + { + buffer.sprintf("%s_%s_%s",m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data()); + } + + void DccCanvasWindow::ownMessage(const char * text, bool bUserFeedback) + { + KviCString buf(KviCString::Format,"%s\r\n",text); + // m_pSlaveThread->sendRawData(buf.ptr(),buf.len()); + + if(bUserFeedback) + m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG, + m_pDescriptor->szLocalNick.toUtf8().data(),m_pDescriptor->szLocalUser.toUtf8().data(), + m_pDescriptor->szLocalHost.toUtf8().data(),text); + } + + void DccCanvasWindow::ownAction(const char * text) + { + KviCString buf(KviCString::Format,"%cACTION %s%c\r\n",text); + // m_pSlaveThread->sendRawData(buf.ptr(),buf.len()); + output(KVI_OUT_ACTION,"%Q %s",&(m_pDescriptor->szLocalNick),text); + } + + bool DccCanvasWindow::event(QEvent *e) + { + // if(e->type() == KVI_THREAD_EVENT) + // { + // switch(((KviThreadEvent *)e)->id()) + // { + // case KVI_DCC_THREAD_EVENT_ERROR: + // { + // int * err = ((KviThreadDataEvent *)e)->getData(); + // output(KVI_OUT_DCCERROR,__tr("ERROR: %s"),kvi_getErrorString(*err)); + // delete err; + // return true; + // } + // break; + // case KVI_DCC_THREAD_EVENT_DATA: + // { + // KviCString * d = ((KviThreadDataEvent *)e)->getData(); + // if(d->firstCharIs(0x01)) + // { + // d->cutLeft(1); + // if(d->lastCharIs(0x01))d->cutRight(1); + // if(kvi_strEqualCIN("ACTION",d->ptr(),6))d->cutLeft(6); + // d->stripLeftWhiteSpace(); + // output(KVI_OUT_ACTION,"%s %s",m_pDescriptor->szNick.ptr(),d->ptr()); + // } else { + // + //#ifdef COMPILE_CRYPT_SUPPORT + // if(KviCryptSessionInfo * cinf = cryptSessionInfo()) + // { + // if(cinf->bDoDecrypt) + // { + // if(cinf->pEngine->isCryptographicEngine() && (*(d->ptr()) == KVI_TEXT_CRYPT)) + // { + // KviCString decryptedStuff; + // if(cinf->pEngine->decrypt(d->ptr() + 1,decryptedStuff)) + // { + // m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSGCRYPTED, + // m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(), + // m_pDescriptor->szHost.ptr(),decryptedStuff.ptr()); + // } else { + // output(KVI_OUT_SYSTEMERROR, + // __tr("The following message looks like an encrypted one, but the crypting engine failed to decode it: %s"), + // cinf->pEngine->lastError()); + // m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG, + // m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(), + // m_pDescriptor->szHost.ptr(),d->ptr() + 1); + // } + // delete d; + // return true; + // } else { + // if(!(cinf->pEngine->isCryptographicEngine())) + // { + // KviCString decryptedStuff; + // if(cinf->pEngine->decrypt(d->ptr(),decryptedStuff)) + // { + // m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG, + // m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(), + // m_pDescriptor->szHost.ptr(),decryptedStuff.ptr()); + // delete d; + // return true; + // } else { + // output(KVI_OUT_SYSTEMERROR, + // __tr("The following message looks like an encrypted one, but the crypting engine failed to decode it: %s"), + // cinf->pEngine->lastError()); + // } + // } + // } + // } + // } + //#endif + // m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG, + // m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(), + // m_pDescriptor->szHost.ptr(),d->ptr()); + // } + // delete d; + // return true; + // } + // break; + // } + // } + return KviWindow::event(e); + } + + void DccCanvasWindow::resizeEvent(QResizeEvent *e) + { + int hght = m_pInput->heightHint(); + // int hght2 = m_pTopSplitter->sizeHint().height(); + // m_pTopSplitter->setGeometry(0,0,width(),hght2); + m_pSplitter->setGeometry(0,0,width(),height() - hght); + m_pInput->setGeometry(0,height() - hght,width(),hght); + } + + QSize DccCanvasWindow::sizeHint() const + { + QSize ret(m_pIrcView->sizeHint().width(), + m_pIrcView->sizeHint().height() + m_pInput->heightHint()); + return ret; + } + + void DccCanvasWindow::handleMarshalError(int err) + { + QString sss = KviError::getDescription(err); + output(KVI_OUT_DCCERROR,__tr2qs_ctx("DCC Failed: %Q","dcc"),&sss); + } + + void DccCanvasWindow::connected() + { + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Connected to %Q:%Q","dcc"), + &(m_pMarshal->remoteIp()),&(m_pMarshal->remotePort())); + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Local end is %Q:%Q","dcc"), + &(m_pMarshal->localIp()),&(m_pMarshal->localPort())); + if(!(m_pDescriptor->bActive)) + { + // PASSIVE CONNECTION...Find out the remote end + m_pDescriptor->szIp = m_pMarshal->remoteIp(); + m_pDescriptor->szPort = m_pMarshal->remotePort(); + m_pDescriptor->szHost = m_pMarshal->remoteIp(); + } + updateCaption(); + // m_pSlaveThread = new KviDccCanvasThread(this,m_pMarshal->releaseSocket()); + // m_pSlaveThread->start(); + } + + #include "m_DccCanvasWindow.moc" +#endif diff --git a/src/modules/dcc/DccCanvasWindow.h b/src/modules/dcc/DccCanvasWindow.h new file mode 100644 index 000000000..c931759b6 --- /dev/null +++ b/src/modules/dcc/DccCanvasWindow.h @@ -0,0 +1,69 @@ +#ifndef _CANVAS_H_ +#define _CANVAS_H_ +//============================================================================= +// +// File : DccCanvasWindow.h +// Creation date : Sun Jul 29 07 2001 20:17:12 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "DccBroker.h" + +#ifdef COMPILE_DCC_CANVAS + #include "DccDescriptor.h" + #include "DccWindow.h" + #include "DccThread.h" + + #include "KviWindow.h" + #include "KviCString.h" + #include "KviPointerList.h" + + class DccMarshal; + class DccCanvasWidget; + class QSplitter; + + class DccCanvasWindow : public DccWindow + { + Q_OBJECT + public: + DccCanvasWindow(KviMainWindow *pFrm,DccDescriptor * dcc,const char * name); + ~DccCanvasWindow(); + protected: + // KviDccCanvasThread * m_pSlaveThread; + DccCanvasWidget * m_pCanvas; + // QSplitter * m_pTopSplitter; + QString m_szTarget; + protected: + virtual const QString &target(); + virtual void fillCaptionBuffers(); + virtual void getBaseLogFileName(KviCString &buffer); + virtual QPixmap * myIconPtr(); + virtual void resizeEvent(QResizeEvent *e); + virtual QSize sizeHint() const; + virtual bool event(QEvent *e); + virtual void ownMessage(const char *text, bool bUserFeedback = true); + virtual void ownAction(const char *text); + protected slots: + void handleMarshalError(int err); + void connected(); + }; +#endif + +#endif // _CANVAS_H_ diff --git a/src/modules/dcc/DccChatWindow.cpp b/src/modules/dcc/DccChatWindow.cpp new file mode 100644 index 000000000..bf5a935c9 --- /dev/null +++ b/src/modules/dcc/DccChatWindow.cpp @@ -0,0 +1,893 @@ +//============================================================================= +// +// File : DccChatWindow.cpp +// Creation date : Tue Sep 20 09 2000 15:13:13 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "DccChatWindow.h" +#include "DccMarshal.h" +#include "DccBroker.h" + +#ifdef COMPILE_ON_WINDOWS + // Ugly Windoze compiler... + #include "DccDialog.h" +#endif + +#include "kvi_debug.h" +#include "KviOptions.h" +#include "KviInput.h" +#include "KviIrcView.h" +#include "KviIconManager.h" +#include "KviLocale.h" +#include "kvi_out.h" +#include "KviNetUtils.h" +#include "KviConsoleWindow.h" +#include "KviMainWindow.h" +#include "KviMemory.h" +#include "KviMemory.h" +#include "KviThread.h" +#include "KviIrcSocket.h" +#include "kvi_settings.h" +#include "kvi_socket.h" +#include "KviApplication.h" +#include "KviParameterList.h" +#include "KviIrcConnection.h" +#include "KviIrcConnectionUserInfo.h" +#include "KviKvsEventTriggers.h" +#include "KviMircCntrl.h" +#include "KviTalVBox.h" + +#include +#include +#include +#include //for Qt::escape + +#ifdef COMPILE_CRYPT_SUPPORT + #include "KviCryptEngine.h" + #include "KviCryptController.h" +#endif + +#ifdef COMPILE_SSL_SUPPORT + #include "KviSSLMaster.h" +#endif + +extern DccBroker * g_pDccBroker; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////// +////// WINDOW +////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +DccChatWindow::DccChatWindow(KviMainWindow *pFrm,DccDescriptor * dcc,const char * name) +: DccWindow(KVI_WINDOW_TYPE_DCCCHAT,pFrm,name,dcc) +{ + m_pButtonBox = new KviTalHBox(this); + + m_pLabel = new KviThemedLabel(m_pButtonBox, this, "dcc_chat_label"); + m_pLabel->setText(name); + m_pButtonBox->setStretchFactor(m_pLabel,1); + + m_pButtonContainer= new KviTalHBox(m_pButtonBox); + createTextEncodingButton(m_pButtonContainer); + +#ifdef COMPILE_CRYPT_SUPPORT + createCryptControllerButton(m_pButtonContainer); +#endif + + m_pSplitter = new KviTalSplitter(Qt::Horizontal,this); + m_pSplitter->setObjectName("dcc_chat_splitter"); + m_pSplitter->setChildrenCollapsible(false); + + m_pIrcView = new KviIrcView(m_pSplitter,pFrm,this); + connect(m_pIrcView,SIGNAL(rightClicked()),this,SLOT(textViewRightClicked())); + m_pInput = new KviInput(this); + + //setFocusHandler(m_pInput,this); + + m_pSlaveThread = 0; + + if(KVI_OPTION_BOOL(KviOption_boolAutoLogDccChat))m_pIrcView->startLogging(); + + m_pMarshal = new DccMarshal(this); + connect(m_pMarshal,SIGNAL(error(int)),this,SLOT(handleMarshalError(int))); + connect(m_pMarshal,SIGNAL(connected()),this,SLOT(connected())); + connect(m_pMarshal,SIGNAL(inProgress()),this,SLOT(connectionInProgress())); +#ifdef COMPILE_SSL_SUPPORT + connect(m_pMarshal,SIGNAL(startingSSLHandshake()),this,SLOT(startingSSLHandshake())); + connect(m_pMarshal,SIGNAL(sslError(const char *)),this,SLOT(sslError(const char *))); +#endif + + m_pSlaveThread = 0; + + startConnection(); +} + +DccChatWindow::~DccChatWindow() +{ + g_pDccBroker->unregisterDccWindow(this); + if(m_pSlaveThread) + { + m_pSlaveThread->terminate(); + delete m_pSlaveThread; + m_pSlaveThread = 0; + } + KviThreadManager::killPendingEvents(this); +} + +void DccChatWindow::textViewRightClicked() +{ + KVS_TRIGGER_EVENT_1(KviEvent_OnDCCChatPopupRequest,this,m_pDescriptor->idString()); +} + +void DccChatWindow::triggerCreationEvents() +{ + KVS_TRIGGER_EVENT_1(KviEvent_OnDCCChatWindowCreated,this,m_pDescriptor->idString()); +} + +void DccChatWindow::triggerDestructionEvents() +{ + KVS_TRIGGER_EVENT_1(KviEvent_OnDCCChatWindowClosing,this,m_pDescriptor->idString()); +} + +void DccChatWindow::startConnection() +{ + if(!(m_pDescriptor->bActive)) + { + // PASSIVE CONNECTION + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Attempting a passive DCC %s connection","dcc"),m_pDescriptor->szType.toUtf8().data()); +#ifdef COMPILE_SSL_SUPPORT + KviError::Code eError = m_pMarshal->dccListen(m_pDescriptor->szListenIp,m_pDescriptor->szListenPort,m_pDescriptor->bDoTimeout,m_pDescriptor->bIsSSL); +#else + KviError::Code eError = m_pMarshal->dccListen(m_pDescriptor->szListenIp,m_pDescriptor->szListenPort,m_pDescriptor->bDoTimeout); +#endif + if(eError != KviError::Success) + handleMarshalError(eError); + } else { + // ACTIVE CONNECTION + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Attempting an active DCC %s connection","dcc"),m_pDescriptor->szType.toUtf8().data()); +#ifdef COMPILE_SSL_SUPPORT + KviError::Code eError = m_pMarshal->dccConnect(m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data(),m_pDescriptor->bDoTimeout,m_pDescriptor->bIsSSL); +#else + KviError::Code eError = m_pMarshal->dccConnect(m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data(),m_pDescriptor->bDoTimeout); +#endif + if(eError != KviError::Success) + handleMarshalError(eError); + } +} + +void DccChatWindow::connectionInProgress() +{ + if(m_pDescriptor->bActive) + { + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Contacting host %Q on port %Q","dcc"),&(m_pDescriptor->szIp),&(m_pDescriptor->szPort)); + } else { + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Listening on interface %Q port %Q","dcc"),&(m_pMarshal->localIp()),&(m_pMarshal->localPort())); + + if(m_pDescriptor->bSendRequest) + { + KviCString ip; + if(!m_pDescriptor->szFakeIp.isEmpty()) + { + ip = m_pDescriptor->szFakeIp; + } else { + ip = m_pDescriptor->szListenIp; + + if(KVI_OPTION_BOOL(KviOption_boolDccGuessIpFromServerWhenLocalIsUnroutable)) + { + if(!kvi_isRoutableIpString(ip.ptr())) + { + // try to get the IP that the IRC server can see + if(m_pDescriptor->console()) + { + KviCString tmp = m_pDescriptor->console()->connection() ? m_pDescriptor->console()->connection()->userInfo()->hostIp().toUtf8().data() : ""; + if(tmp.hasData()) + { + ip = tmp; + output(KVI_OUT_DCCMSG,__tr2qs_ctx("The local IP address is private, determining from IRC server: %s","dcc"),ip.ptr()); + } else { + output(KVI_OUT_DCCMSG,__tr2qs_ctx("The local IP address is private, but unable to determine it from the IRC server","dcc")); + } + } else { + output(KVI_OUT_DCCMSG,__tr2qs_ctx("The local IP address is private, but have no IRC server to determine it from","dcc")); + } + } + } + } + + QString port = !m_pDescriptor->szFakePort.isEmpty() ? m_pDescriptor->szFakePort : QString(m_pMarshal->localPort()); + + //FIXME: #warning "OPTION FOR SENDING 127.0.0.1 and so on (not an unsigned number)" + struct in_addr a; + if(KviNetUtils::stringIpToBinaryIp(ip.ptr(),&a))ip.setNum(htonl(a.s_addr)); + + QString szReq = QString("PRIVMSG %1 :%2DCC %3 chat %4 %5").arg(m_pDescriptor->szNick, QChar(0x01), m_pDescriptor->szType, ip.ptr(), port); + + if(m_pDescriptor->isZeroPortRequest()) + { + szReq.append(" "); + szReq+=m_pDescriptor->zeroPortRequestTag(); + } + szReq.append((char)(0x01)); + + m_pDescriptor->console()->connection()->sendData(m_pDescriptor->console()->connection()->encodeText(szReq).data()); + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Sent DCC %Q request to %Q, waiting for the remote client to connect...","dcc"), + &(m_pDescriptor->szType),&(m_pDescriptor->szNick)); + //qDebug(m_pDescriptor->szNick); + } else output(KVI_OUT_DCCMSG,__tr2qs_ctx("DCC %Q request not sent, awaiting manual connection","dcc"),&(m_pDescriptor->szType)); + } + KVS_TRIGGER_EVENT_1(KviEvent_OnDCCChatConnectionInProgress,this,m_pDescriptor->idString()); +} + +void DccChatWindow::startingSSLHandshake() +{ +#ifdef COMPILE_SSL_SUPPORT + outputNoFmt(KVI_OUT_SSL,__tr2qs_ctx("Low-level transport connection established","dcc")); + outputNoFmt(KVI_OUT_SSL,__tr2qs_ctx("Starting Secure Socket Layer handshake","dcc")); +#endif +} + +void DccChatWindow::sslError(const char * msg) +{ +#ifdef COMPILE_SSL_SUPPORT + if(!KVS_TRIGGER_EVENT_2_HALTED(KviEvent_OnDCCChatError,this,QString(msg),m_pDescriptor->idString())) + output(KVI_OUT_DCCERROR,__tr2qs_ctx("[SSL ERROR]: %s","dcc"),msg); +#endif +} + +const QString & DccChatWindow::target() +{ + // This may change on the fly... + m_szTarget = m_pDescriptor->szNick; + m_szTarget += "@"; + m_szTarget += m_pDescriptor->szIp; + m_szTarget += ":"; + m_szTarget += m_pDescriptor->szPort; + return m_szTarget; +} + +void DccChatWindow::fillCaptionBuffers() +{ + QString tmp = QString("DCC %1 %2@%3:%4").arg( +#ifdef COMPILE_SSL_SUPPORT + m_pDescriptor->bIsSSL ? "SChat" : "Chat", +#else + "Chat", +#endif + m_pDescriptor->szNick, m_pDescriptor->szIp, m_pDescriptor->szPort); + + m_szPlainTextCaption = tmp; +} + +QPixmap * DccChatWindow::myIconPtr() +{ + return g_pIconManager->getSmallIcon(KVI_SMALLICON_DCCMSG); +} + +void DccChatWindow::getBaseLogFileName(QString &buffer) +{ + buffer.sprintf("%s_%s_%s",m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data()); +} + +void DccChatWindow::ownMessage(const QString &text, bool bUserFeedback) +{ + if(!m_pSlaveThread) + { + output(KVI_OUT_SYSTEMWARNING,__tr2qs_ctx("Cannot send data: No active connection","dcc")); + return; + } + + QByteArray szData = encodeText(text); + const char * d = szData.data(); + if(!d)return; + +#ifdef COMPILE_CRYPT_SUPPORT + if(cryptSessionInfo()) + { + if(cryptSessionInfo()->m_bDoEncrypt) + { + if(*d != KviMircCntrl::CryptEscape) + { + KviCString encrypted; + cryptSessionInfo()->m_pEngine->setMaxEncryptLen(-1); + switch(cryptSessionInfo()->m_pEngine->encrypt(d,encrypted)) + { + case KviCryptEngine::Encrypted: + { + KviCString buf(KviCString::Format,"%s\r\n",encrypted.ptr()); + m_pSlaveThread->sendRawData(buf.ptr(),buf.len()); + if(bUserFeedback) + m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSGCRYPTED, + m_pDescriptor->szLocalNick.toUtf8().data(),m_pDescriptor->szLocalUser.toUtf8().data(), + m_pDescriptor->szLocalHost.toUtf8().data(),text,KviConsoleWindow::NoNotifications); + } + break; + case KviCryptEngine::Encoded: + { + KviCString buf(KviCString::Format,"%s\r\n",encrypted.ptr()); + m_pSlaveThread->sendRawData(buf.ptr(),buf.len()); + if(bUserFeedback) + { + QString encr = decodeText(encrypted.ptr()); + m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG, + m_pDescriptor->szLocalNick.toUtf8().data(),m_pDescriptor->szLocalUser.toUtf8().data(), + m_pDescriptor->szLocalHost.toUtf8().data(),encr,KviConsoleWindow::NoNotifications); + } + } + break; + default: // also case KviCryptEngine::EncryptError + { + QString szErr = cryptSessionInfo()->m_pEngine->lastError(); + output(KVI_OUT_SYSTEMERROR, + __tr2qs_ctx("The crypto engine was not able to encrypt the current message (%Q): %Q, no data was sent to the remote end","dcc"), + &text,&szErr); + } + break; + } + return; + } else { + d++; //eat the escape code + KviCString buf(KviCString::Format,"%s\r\n",d); + QString tmp = text.right(text.length() - 1); + m_pSlaveThread->sendRawData(buf.ptr(),buf.len()); + + if(bUserFeedback) + m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG, + m_pDescriptor->szLocalNick.toUtf8().data(),m_pDescriptor->szLocalUser.toUtf8().data(), + m_pDescriptor->szLocalHost.toUtf8().data(),tmp,KviConsoleWindow::NoNotifications); + return; + } + } + } +#endif + KviCString buf(KviCString::Format,"%s\r\n",d); + m_pSlaveThread->sendRawData(buf.ptr(),buf.len()); + + if(bUserFeedback) + m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG, + m_pDescriptor->szLocalNick.toUtf8().data(),m_pDescriptor->szLocalUser.toUtf8().data(), + m_pDescriptor->szLocalHost.toUtf8().data(),text,KviConsoleWindow::NoNotifications); +} + +const QString & DccChatWindow::localNick() +{ + // FIXME: This is just a complete HACK + m_szLocalNick = m_pDescriptor->szLocalNick; + return m_szLocalNick; +} + +void DccChatWindow::ownAction(const QString &text) +{ + if(m_pSlaveThread) + { + QString szTmpBuffer; + //see bug ticket #220 + if(KVI_OPTION_BOOL(KviOption_boolStripMircColorsInUserMessages)) + { + szTmpBuffer = KviMircCntrl::stripControlBytes(text); + } else { + szTmpBuffer = text; + } + + QByteArray szData = encodeText(szTmpBuffer); + const char * d = szData.data(); + if(!d) + return; + KviCString buf(KviCString::Format,"%cACTION %s%c\r\n",0x01,d,0x01); + m_pSlaveThread->sendRawData(buf.ptr(),buf.len()); + output(KVI_OUT_ACTION,"%Q %Q",&(m_pDescriptor->szLocalNick),&szTmpBuffer); + } else { + output(KVI_OUT_SYSTEMWARNING,__tr2qs_ctx("Cannot send data: No active connection","dcc")); + } +} + +bool DccChatWindow::event(QEvent *e) +{ + if(e->type() == KVI_THREAD_EVENT) + { + switch(((KviThreadEvent *)e)->id()) + { + case KVI_DCC_THREAD_EVENT_ERROR: + { + KviError::Code * pError = ((KviThreadDataEvent *)e)->getData(); + QString szErr = KviError::getDescription(*pError); + if(!KVS_TRIGGER_EVENT_2_HALTED(KviEvent_OnDCCChatError,this,szErr,m_pDescriptor->idString())) + output(KVI_OUT_DCCERROR,__tr2qs_ctx("ERROR: %Q","dcc"),&szErr); + KVS_TRIGGER_EVENT_1(KviEvent_OnDCCChatDisconnected,this,m_pDescriptor->idString()); + delete pError; + return true; + } + break; + case KVI_DCC_THREAD_EVENT_DATA: + { + KviCString * encoded = ((KviThreadDataEvent *)e)->getData(); + KviCString d=KviCString(decodeText(encoded->ptr())); + if(d.firstCharIs(0x01)) + { + d.cutLeft(1); + if(d.lastCharIs(0x01))d.cutRight(1); + if(kvi_strEqualCIN("ACTION",d.ptr(),6))d.cutLeft(6); + d.stripLeftWhiteSpace(); + output(KVI_OUT_ACTION,"%Q %s",&(m_pDescriptor->szNick),d.ptr()); + if(!hasAttention()) + { + if(KVI_OPTION_BOOL(KviOption_boolFlashDccChatWindowOnNewMessages)) + { + demandAttention(); + } + if(KVI_OPTION_BOOL(KviOption_boolPopupNotifierOnNewDccChatMessages)) + { + QString szMsg = ""; + szMsg += m_pDescriptor->szNick; + szMsg += " "; + szMsg += Qt::escape(QString(d.ptr())); + //qDebug("KviIrcServerParser_ctcp.cpp:975 debug: %s",szMsg.data()); + g_pApp->notifierMessage(this,KVI_OPTION_MSGTYPE(KVI_OUT_ACTION).pixId(),szMsg,KVI_OPTION_UINT(KviOption_uintNotifierAutoHideTime)); + } + } + } else { + +#ifdef COMPILE_CRYPT_SUPPORT + if(KviCryptSessionInfo * cinf = cryptSessionInfo()) + { + if(cinf->m_bDoDecrypt) + { + KviCString decryptedStuff; + switch(cinf->m_pEngine->decrypt(d.ptr(),decryptedStuff)) + { + case KviCryptEngine::DecryptOkWasEncrypted: + case KviCryptEngine::DecryptOkWasEncoded: + case KviCryptEngine::DecryptOkWasPlainText: + if(!KVS_TRIGGER_EVENT_2_HALTED(KviEvent_OnDCCChatMessage,this,QString(decryptedStuff.ptr()),m_pDescriptor->idString())) + { + m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG, + m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szUser.toUtf8().data(), + m_pDescriptor->szHost.toUtf8().data(),decryptedStuff.ptr()); + } + delete encoded; + return true; + break; + + default: // also case KviCryptEngine::DecryptError + { + QString szErr = cinf->m_pEngine->lastError(); + output(KVI_OUT_SYSTEMERROR, + __tr2qs_ctx("The following message appears to be encrypted, but the crypto engine failed to decode it: %Q","dcc"), + &szErr); + } + break; + } + } + } else { +#endif + // FIXME! + if(!KVS_TRIGGER_EVENT_2_HALTED(KviEvent_OnDCCChatMessage,this,QString(d.ptr()),m_pDescriptor->idString())) + { + m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG, + m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szUser.toUtf8().data(), + m_pDescriptor->szHost.toUtf8().data(),d.ptr()); + if(!hasAttention()) + { + if(KVI_OPTION_BOOL(KviOption_boolFlashDccChatWindowOnNewMessages)) + { + demandAttention(); + } + if(KVI_OPTION_BOOL(KviOption_boolPopupNotifierOnNewDccChatMessages)) + { + QString szMsg = Qt::escape(QString(d.ptr())); + g_pApp->notifierMessage(this,KVI_SMALLICON_DCCCHATMSG,szMsg,KVI_OPTION_UINT(KviOption_uintNotifierAutoHideTime)); + } + } + } +#ifdef COMPILE_CRYPT_SUPPORT + } +#endif + } + delete encoded; + return true; + } + break; + } + } + return KviWindow::event(e); +} + +void DccChatWindow::resizeEvent(QResizeEvent *) +{ + int hght = m_pInput->heightHint(); + int hght2 = m_pButtonBox->sizeHint().height(); + m_pButtonBox->setGeometry(0,0,width(),hght2); + m_pSplitter->setGeometry(0,hght2,width(),height() - (hght + hght2)); + m_pInput->setGeometry(0,height() - hght,width(),hght); +} + +QSize DccChatWindow::sizeHint() const +{ + QSize ret(m_pIrcView->sizeHint().width(), + m_pIrcView->sizeHint().height() + m_pInput->heightHint()); + return ret; +} + +void DccChatWindow::handleMarshalError(KviError::Code eError) +{ + QString szErr = KviError::getDescription(eError); + if(!KVS_TRIGGER_EVENT_2_HALTED(KviEvent_OnDCCChatError,this,szErr,m_pDescriptor->idString())) + output(KVI_OUT_DCCERROR,__tr2qs_ctx("DCC %Q failed: %Q","dcc"),&(m_pDescriptor->szType),&szErr); +} + +void DccChatWindow::connected() +{ + if(!(m_pDescriptor->bActive)) + { + // PASSIVE CONNECTION...Find out the remote end + m_pDescriptor->szIp = m_pMarshal->remoteIp(); + m_pDescriptor->szPort = m_pMarshal->remotePort(); + m_pDescriptor->szHost = m_pMarshal->remoteIp(); + } + + updateCaption(); + + m_pSlaveThread = new DccChatThread(this,m_pMarshal->releaseSocket()); + +#ifdef COMPILE_SSL_SUPPORT + KviSSL * s = m_pMarshal->releaseSSL(); + if(s) + { + KviSSLMaster::printSSLConnectionInfo(this,s); + m_pSlaveThread->setSSL(s); + } +#endif + m_pSlaveThread->start(); + + if(!KVS_TRIGGER_EVENT_1_HALTED(KviEvent_OnDCCChatConnected,this,m_pDescriptor->idString())) + { + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Connected to %Q:%Q","dcc"), + &(m_pMarshal->remoteIp()),&(m_pMarshal->remotePort())); + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Local end is %Q:%Q","dcc"), + &(m_pMarshal->localIp()),&(m_pMarshal->localPort())); +#ifdef COMPILE_SSL_SUPPORT + QString tmp = QString("dcc: %1 %2@%3:%4").arg(m_pDescriptor->bIsSSL ? "SChat" : "Chat", m_pDescriptor->szNick, m_pDescriptor->szIp, m_pDescriptor->szPort); +#else + QString tmp = QString("dcc: %1 %2@%3:%4").arg("Chat", m_pDescriptor->szNick, m_pDescriptor->szIp, m_pDescriptor->szPort); +#endif + m_pLabel->setText(tmp); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////// +////// THREAD +////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +DccChatThread::DccChatThread(KviWindow *wnd,kvi_socket_t fd) +: DccThread(wnd,fd) +{ + m_pOutBuffers = new KviPointerList; + m_pOutBuffers->setAutoDelete(true); +} + +DccChatThread::~DccChatThread() +{ + if(m_pOutBuffers)delete m_pOutBuffers; +} + +void DccChatThread::run() +{ + KviDccThreadIncomingData data; + data.iLen = 0; + data.buffer = 0; + + for(;;) + { + // Dequeue events + while(KviThreadEvent * e = dequeueEvent()) + { + if(e->id() == KVI_THREAD_EVENT_TERMINATE) + { + delete e; + goto out_of_the_loop; + } else { + // Other events are senseless to us + delete e; + } + } + + bool bCanRead; + bool bCanWrite; + if(kvi_select(m_fd,&bCanRead,&bCanWrite)) + { + if(bCanWrite) + { + if(!tryFlushOutBuffers())goto out_of_the_loop; + } + if(bCanRead) + { + data.buffer = (char *) KviMemory::reallocate(data.buffer,(data.iLen + 512) * sizeof(char)); + int readLen; +#ifdef COMPILE_SSL_SUPPORT + if(m_pSSL) + { + readLen = m_pSSL->read(data.buffer + data.iLen,512); + } else { +#endif + readLen = kvi_socket_recv(m_fd,data.buffer + data.iLen,512); +#ifdef COMPILE_SSL_SUPPORT + } +#endif + if(readLen > 0) + { + data.iLen += readLen; + data.buffer = (char *)KviMemory::reallocate(data.buffer,data.iLen * sizeof(char)); + if(!handleIncomingData(&data,false))break; // non critical... + } else { + +#ifdef COMPILE_SSL_SUPPORT + if(m_pSSL) + { + // ssl error....? + switch(m_pSSL->getProtocolError(readLen)) + { + case KviSSL::ZeroReturn: + readLen = 0; + break; + case KviSSL::WantRead: + case KviSSL::WantWrite: + // hmmm... + break; + case KviSSL::SyscallError: + { + int iE = m_pSSL->getLastError(true); + if(iE != 0) + { + raiseSSLError(); + postErrorEvent(KviError::SSLError); + goto out_of_the_loop; + } + } + break; + case KviSSL::SSLError: + { + raiseSSLError(); + postErrorEvent(KviError::SSLError); + goto out_of_the_loop; + } + break; + default: + // Raise unknown SSL ERROR + postErrorEvent(KviError::SSLError); + goto out_of_the_loop; + break; + } + } +#endif + if(data.iLen > 0) + { + data.buffer = (char *)KviMemory::reallocate(data.buffer,data.iLen * sizeof(char)); + } else { + KviMemory::free(data.buffer); + data.buffer = 0; + } + + if(!handleInvalidSocketRead(readLen)) + { + if(data.iLen)handleIncomingData(&data,true); // critical + KVI_ASSERT(!data.iLen); + break; // error + } + } + } + msleep(100); + } + } + +out_of_the_loop: + + + if(data.iLen)KviMemory::free(data.buffer); + +#ifdef COMPILE_SSL_SUPPORT + if(m_pSSL) + { + KviSSLMaster::freeSSL(m_pSSL); + m_pSSL = 0; + } +#endif + + if(m_fd != KVI_INVALID_SOCKET)::kvi_socket_close(m_fd); + m_fd = KVI_INVALID_SOCKET; +} + +bool DccChatThread::handleIncomingData(KviDccThreadIncomingData * data,bool bCritical) +{ + KVI_ASSERT(data->iLen); + KVI_ASSERT(data->buffer); + char * aux = data->buffer; + char * end = data->buffer + data->iLen; + while(aux != end) + { + if((*aux == '\n') || (*aux == '\0')) + { + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_DATA); + // The left part is len chars long + int len = aux - data->buffer; +// qDebug("LEN = %d, iLen = %d",len,data->iLen); +//#warning "DO IT BETTER (the \r cutting)" + KviCString * s = new KviCString(data->buffer,len); + if(s->lastCharIs('\r'))s->cutRight(1); + e->setData(s); + // but we cut also \n (or \0) + ++aux; + // so len += 1; --> new data->iLen -= len; + data->iLen -= (len + 1); +// qDebug("iLen now = %d",data->iLen); + KVI_ASSERT(data->iLen >= 0); + if(data->iLen > 0) + { + // memmove the remaining part to the beginning + // aux points after \n or \0 + KviMemory::move(data->buffer,aux,data->iLen); + data->buffer = (char *)KviMemory::reallocate(data->buffer,data->iLen); + end = data->buffer + data->iLen; + aux = data->buffer; + } else { + // no more data in the buffer + KVI_ASSERT(data->iLen == 0); + KviMemory::free(data->buffer); + data->buffer = end = aux = 0; + } + postEvent(parent(),e); + } else aux++; +// qDebug("PASSING CHAR %c",*aux); + } + // now aux == end + if(bCritical) + { + // need to flush everything... + if(data->iLen > 0) + { + // in the last part there are no NULL and \n chars + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_DATA); + KviCString * s = new KviCString(data->buffer,data->iLen); + if(s->lastCharIs('\r'))s->cutRight(1); + e->setData(s); + data->iLen = 0; + KviMemory::free(data->buffer); + data->buffer = 0; + postEvent(parent(),e); + } + } + return true; +} + +void DccChatThread::sendRawData(const void * buffer,int len) +{ + m_pMutex->lock(); + m_pOutBuffers->append(new KviDataBuffer((unsigned int)len,(const unsigned char *)buffer)); + m_pMutex->unlock(); +} + +bool DccChatThread::tryFlushOutBuffers() +{ + bool bRet = true; + m_pMutex->lock(); + while(KviDataBuffer * b = m_pOutBuffers->first()) + { + int sentLen; +#ifdef COMPILE_SSL_SUPPORT + if(m_pSSL) + { + sentLen = m_pSSL->write((const char *)b->data(),b->size()); + } else { +#endif + sentLen = kvi_socket_send(m_fd,b->data(),b->size()); +#ifdef COMPILE_SSL_SUPPORT + } +#endif + if(sentLen > 0) + { + if(sentLen == b->size())m_pOutBuffers->removeFirst(); + else { + // just a part + b->remove((unsigned int)sentLen); + break; + } + } else { +#ifdef COMPILE_SSL_SUPPORT + if(m_pSSL) + { + // ops...might be an SSL error + switch(m_pSSL->getProtocolError(sentLen)) + { + case KviSSL::WantWrite: + case KviSSL::WantRead: + // Async continue... + goto handle_system_error; + break; + case KviSSL::SyscallError: + if(sentLen == 0) + { + raiseSSLError(); + postErrorEvent(KviError::RemoteEndClosedConnection); + bRet = false; + goto out_of_the_loop; + } else { + int iSSLErr = m_pSSL->getLastError(true); + if(iSSLErr != 0) + { + raiseSSLError(); + postErrorEvent(KviError::SSLError); + bRet = false; + goto out_of_the_loop; + } else { + goto handle_system_error; + } + } + break; + case KviSSL::SSLError: + raiseSSLError(); + postErrorEvent(KviError::SSLError); + bRet = false; + goto out_of_the_loop; + break; + default: + postErrorEvent(KviError::SSLError); + bRet = false; + goto out_of_the_loop; + break; + } + } +#endif +handle_system_error: + if(sentLen < 0) + { + int err = kvi_socket_error(); +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + if((err != EAGAIN) || (err != EINTR) || (err != WSAEWOULDBLOCK)) +#else + if((err != EAGAIN)||(err != EINTR)) +#endif + { + postErrorEvent(KviError::translateSystemError(err)); + bRet = false; + goto out_of_the_loop; + } + } + break; // send error + } + } +out_of_the_loop: + m_pMutex->unlock(); + return bRet; +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_DccChatWindow.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/dcc/DccChatWindow.h b/src/modules/dcc/DccChatWindow.h new file mode 100644 index 000000000..7a2eb1531 --- /dev/null +++ b/src/modules/dcc/DccChatWindow.h @@ -0,0 +1,106 @@ +#ifndef _CHAT_H_ +#define _CHAT_H_ +//============================================================================= +// +// File : DccChatWindow.h +// Creation date : Tue Sep 20 09 2000 15:11:12 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "DccDescriptor.h" +#include "DccThread.h" +#include "DccWindow.h" + +#include "KviDataBuffer.h" +#include "KviPointerList.h" +#include "KviThemedLabel.h" +#include "KviCString.h" +#include "KviWindow.h" +#include "KviError.h" + +#ifdef COMPILE_SSL_SUPPORT + class KviSSL; +#endif + +class DccMarshal; +class QSplitter; + +class DccChatThread : public DccThread +{ +public: + DccChatThread(KviWindow * wnd,kvi_socket_t fd); + ~DccChatThread(); +protected: + KviPointerList * m_pOutBuffers; +protected: + virtual void run(); + bool tryFlushOutBuffers(); + // This should handle the incoming data buffer + // must "eat" some data from data.buffer, memmove the remaining part + // to the beginning, kvi_realloc data.buffer and update data.iLen + // If bCritical is true, it should handle the whole data buffer + // since the thread is going to die + // It should return true if the handing was succesfull + // or false if the thread should be stopped + virtual bool handleIncomingData(KviDccThreadIncomingData *data,bool bCritical); +public: + virtual void sendRawData(const void * buffer,int len); // mutex (m_pOutBuffers usage) +}; + + +class DccChatWindow : public DccWindow +{ + Q_OBJECT +public: + DccChatWindow(KviMainWindow *pFrm,DccDescriptor * dcc,const char * name); + ~DccChatWindow(); + QFrame * buttonContainer() { return (QFrame*)m_pButtonContainer; }; +protected: + DccChatThread * m_pSlaveThread; + QString m_szTarget; + QString m_szLocalNick; + KviThemedLabel * m_pLabel; + KviTalHBox * m_pButtonBox; + KviTalHBox * m_pButtonContainer; +protected: + virtual const QString & target(); + virtual void fillCaptionBuffers(); + virtual void getBaseLogFileName(QString &buffer); + virtual QPixmap * myIconPtr(); + virtual void resizeEvent(QResizeEvent *e); + virtual QSize sizeHint() const; + virtual const QString & localNick(); + virtual bool event(QEvent *e); + virtual void ownMessage(const QString &text, bool bUserFeedback = true); + virtual void ownAction(const QString &text); + virtual void triggerCreationEvents(); + virtual void triggerDestructionEvents(); + void startConnection(); + virtual DccThread * getSlaveThread() { return m_pSlaveThread; }; +protected slots: + void handleMarshalError(KviError::Code eError); + void connected(); + void sslError(const char * msg); + void connectionInProgress(); + void startingSSLHandshake(); + void textViewRightClicked(); +}; + +#endif //_CHAT_H_ diff --git a/src/modules/dcc/DccDescriptor.cpp b/src/modules/dcc/DccDescriptor.cpp new file mode 100644 index 000000000..cd50ac319 --- /dev/null +++ b/src/modules/dcc/DccDescriptor.cpp @@ -0,0 +1,231 @@ +//============================================================================= +// +// File : DccDescriptor.cpp +// Creation date : Tue Jul 23 01:11:54 2002 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "DccDescriptor.h" +#include "DccFileTransfer.h" +#include "DccWindow.h" + +#include "KviLocale.h" +#include "KviKvsEventTriggers.h" +#include "KviWindow.h" +#include "KviApplication.h" + +static unsigned int g_uNextDescriptorId = 1; // we use 0 as an invalid descriptor id +static KviPointerHashTable * g_pDescriptorDict = 0; + +KviPointerHashTable * DccDescriptor::descriptorDict() +{ + return g_pDescriptorDict; +} + +DccDescriptor::DccDescriptor(const DccDescriptor & src) +{ + copyFrom(src); +} + +DccDescriptor::DccDescriptor(KviConsoleWindow * pConsole) +{ + m_pConsole = pConsole; + m_pDccWindow = 0; + m_pDccTransfer = 0; + + m_uId = g_uNextDescriptorId; + g_uNextDescriptorId++; + + m_szId.setNum(m_uId); + + if(!g_pDescriptorDict) + { + g_pDescriptorDict = new KviPointerHashTable; + g_pDescriptorDict->setAutoDelete(false); + } + g_pDescriptorDict->replace((long)m_uId,this); + + szNick = __tr_ctx("unknown","dcc"); + szUser = szNick; + szHost = szNick; + + szLocalNick = szNick; + szLocalUser = szNick; + szLocalHost = szNick; + + szIp = szNick; + szPort = szNick; + + + bSendRequest = true; + bDoTimeout = true; + bIsTdcc = false; + bOverrideMinimize = false; + bShowMinimized = false; + bAutoAccept = false; +#ifdef COMPILE_SSL_SUPPORT + bIsSSL = false; +#endif + bRecvFile = false; + bResume = false; + bNoAcks = false; + bIsIncomingAvatar = false; + + iSampleRate = 0; + + m_bCreationEventTriggered = false; +} + +DccDescriptor::~DccDescriptor() +{ + if(m_bCreationEventTriggered) + { + KviWindow * pEventWindow = m_pConsole; + if(!pEventWindow)pEventWindow = g_pApp->activeConsole(); // any console + else { + if(!(g_pApp->windowExists(pEventWindow)))pEventWindow = g_pApp->activeConsole(); + } + + if(pEventWindow) + { + // recheck it again... + if(g_pApp->windowExists(pEventWindow)) + { + KVS_TRIGGER_EVENT_1(KviEvent_OnDCCSessionDestroyed,pEventWindow,m_szId); + } + } + } + + if(g_pDescriptorDict) + { + g_pDescriptorDict->remove((long)m_uId); + if(g_pDescriptorDict->count() < 1) + { + delete g_pDescriptorDict; + g_pDescriptorDict = 0; + } + } + +} + +void DccDescriptor::triggerCreationEvent() +{ + if(m_bCreationEventTriggered) + { + qDebug("Ops.. trying to trigger OnDccSessionCreated twice"); + return; + } + m_bCreationEventTriggered = true; + KviWindow * pEventWindow = m_pConsole; + if(!pEventWindow)pEventWindow = g_pApp->activeConsole(); // any console + if(pEventWindow) + { + KVS_TRIGGER_EVENT_1(KviEvent_OnDCCSessionCreated,pEventWindow,m_szId); + } +} + +DccDescriptor * DccDescriptor::find(unsigned int uId) +{ + if(!g_pDescriptorDict)return 0; + return g_pDescriptorDict->find((long)uId); +} + +void DccDescriptor::copyFrom(const DccDescriptor &src) +{ + m_uId = g_uNextDescriptorId; + g_uNextDescriptorId++; + m_szId.setNum(m_uId); + + if(!g_pDescriptorDict) + { + g_pDescriptorDict = new KviPointerHashTable; + g_pDescriptorDict->setAutoDelete(false); + } + g_pDescriptorDict->replace((long)m_uId,this); + m_bCreationEventTriggered=false; + + m_pDccWindow = src.m_pDccWindow; + m_pDccTransfer = src.m_pDccTransfer; + szType = src.szType; + szNick = src.szNick; + szUser = src.szUser; + szHost = src.szHost; + szLocalNick = src.szLocalNick; + szLocalUser = src.szLocalUser; + szLocalHost = src.szLocalHost; + szIp = src.szIp; + szPort = src.szPort; + m_pConsole = src.console(); + m_szZeroPortRequestTag= src.zeroPortRequestTag(); + bActive = src.bActive; + szListenIp = src.szListenIp; + szListenPort = src.szListenPort; + szFakeIp = src.szFakeIp; + szFakePort = src.szFakePort; + bSendRequest = src.bSendRequest; + bDoTimeout = src.bDoTimeout; + szFileName = src.szFileName; + szFileSize = src.szFileSize; + bResume = src.bResume; + bRecvFile = src.bRecvFile; + bNoAcks = src.bNoAcks; + bIsTdcc = src.bIsTdcc; + bOverrideMinimize = src.bOverrideMinimize; + bShowMinimized = src.bShowMinimized; + bAutoAccept = src.bAutoAccept; + bIsIncomingAvatar = src.bIsIncomingAvatar; + szLocalFileName = src.szLocalFileName; + szLocalFileSize = src.szLocalFileSize; +#ifdef COMPILE_SSL_SUPPORT + bIsSSL = src.bIsSSL; +#endif + // dcc voice only + szCodec = src.szCodec; + iSampleRate = src.iSampleRate; +} + +bool DccDescriptor::isFileUpload() +{ + if(szType.toUpper()=="SEND")return true; + if(szType.toUpper()=="TSEND")return true; +#ifdef COMPILE_SSL_SUPPORT + if(szType.toUpper()=="SSEND")return true; +#endif + return false; +} + +bool DccDescriptor::isFileDownload() +{ + if(szType.toUpper()=="RECV")return true; + if(szType.toUpper()=="TRECV")return true; +#ifdef COMPILE_SSL_SUPPORT + if(szType.toUpper()=="SRECV")return true; +#endif + return false; +} + +bool DccDescriptor::isDccChat() +{ + if(szType.toUpper()=="CHAT")return true; +#ifdef COMPILE_SSL_SUPPORT + if(szType.toUpper()=="SCHAT")return true; +#endif + return false; +} diff --git a/src/modules/dcc/DccDescriptor.h b/src/modules/dcc/DccDescriptor.h new file mode 100644 index 000000000..ae5784dc5 --- /dev/null +++ b/src/modules/dcc/DccDescriptor.h @@ -0,0 +1,158 @@ +#ifndef _DESCRIPTOR_H_ +#define _DESCRIPTOR_H_ +//============================================================================= +// +// File : DccDescriptor.h +// Creation date : Tue Jul 23 01:11:52 2002 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002-2010 Szymon Stefanek (oragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviCString.h" +#include "KviConsoleWindow.h" +#include "KviPointerHashTable.h" + +class DccWindow; +class DccFileTransfer; +class DccDescriptor +{ +public: + DccDescriptor(KviConsoleWindow * pConsole); + DccDescriptor(const DccDescriptor & src); + + ~DccDescriptor(); +protected: + KviConsoleWindow * m_pConsole; + + // mIrc zero port reverse send/chat extension + KviCString m_szZeroPortRequestTag; + + unsigned int m_uId; // this dcc session ID + QString m_szId; + + DccWindow * m_pDccWindow; // 0 if it has no window + DccFileTransfer * m_pDccTransfer; // 0 if it is not a transfer + + bool m_bCreationEventTriggered; +public: + // A console that this DCC is bound to (might be replaced while we wait for user acknowledge in dialogs) + KviConsoleWindow * console() const { return m_pConsole; }; + void setConsole(KviConsoleWindow * c){ m_pConsole = c; }; + + DccWindow * window() const { return m_pDccWindow; }; + void setWindow(DccWindow * w){ m_pDccWindow = w; }; + + DccFileTransfer * transfer() const { return m_pDccTransfer; }; + void setTransfer(DccFileTransfer * t){ m_pDccTransfer = t; }; + + // mIrc zero port reverse send/chat extension + bool isZeroPortRequest() const { return m_szZeroPortRequestTag.hasData(); }; + const char * zeroPortRequestTag() const { return m_szZeroPortRequestTag.ptr(); }; + void setZeroPortRequestTag(const KviCString &szTag){ m_szZeroPortRequestTag = szTag; }; + + unsigned int id() const { return m_uId; }; + const QString & idString() const { return m_szId; }; + static DccDescriptor * find(unsigned int uId); + static KviPointerHashTable * descriptorDict(); + + void triggerCreationEvent(); // this MUST be called by the creator of the descriptor! +private: + void copyFrom(const DccDescriptor &src); +public: + // Generic parameters + QString szType; // DCC protocol : CHAT, SCHAT, SEND, TSSEND.... + + bool bActive; // active or passive connection ? + + QString szNick; // remote user nickname + QString szUser; // remote user name (unknown for passive dcc) + QString szHost; // remote user host (unknown for passive dcc) + + QString szLocalNick; // local user nickname (always from irc) + QString szLocalUser; // local user username (always from irc) + QString szLocalHost; // local user hostname (always from irc) + + QString szIp; // remote user ip (active dcc only) + QString szPort; // remote user port (active dcc only) + + QString szListenIp; // passive only : ip to listen on + QString szListenPort; // passive only : port to listen on + + bool bSendRequest; // passive only : true if we have to send the CTCP request + + QString szFakeIp; // passive only : fake ip to send in the CTCP + QString szFakePort; // passive only : fake port to send in the CTCP + + bool bDoTimeout; // the marshall has to setup a timeout ? + + bool bIsTdcc; // is this a TDCC ? + + bool bOverrideMinimize; // Override the default minimize option ? + bool bShowMinimized; // Show minimized ? (valid if bOverrideMinimize is true) + + bool bAutoAccept; // Auto accepted dcc send/chat ? +#ifdef COMPILE_SSL_SUPPORT + bool bIsSSL; // do we have to use SSL ? +#endif + // Specific parameters + + // DCC SEND/RECV + + QString szFileName; // RECVFILE: incoming file name, SENDFILE: filename sent to the remote end + QString szFileSize; // RECVFILE: incoming file size, SENDFILE: remote resume size + + QString szLocalFileName; // RECVFILE: save file name selected, SENDFILE: file to send + QString szLocalFileSize; // RECVFILE: local file size (to resume), SENDFILE: file to send size + + bool bRecvFile; // do we have to RECEIVE the file or SEND it ? + bool bResume; // do we want to resume ? + bool bNoAcks; // blind dcc send ? (do not receive nor send acknowledges) + + bool bIsIncomingAvatar; // It is an Incoming Avatar DCC SEND ? + + // DCC VOICE + KviCString szCodec; // codec name + int iSampleRate; // Sample rate +public: + QString protocol() const { return szType; }; + bool isActive() const { return bActive; }; + QString remoteNick() const { return szNick; }; + QString remoteUser() const { return szUser; }; + QString remoteHost() const { return szHost; }; + QString remoteIp() const { return szIp; }; + QString remotePort() const { return szPort; }; + QString remoteFileName() const { return szFileName; }; + QString remoteFileSize() const { return szFileSize; }; + QString localNick() const { return szLocalNick; }; + QString localUser() const { return szLocalUser; }; + QString localHost() const { return szLocalHost; }; + QString localIp() const { return szIp; }; + QString localPort() const { return szPort; }; + QString localFileName() const { return szLocalFileName; }; + QString localFileSize() const { return szLocalFileSize; }; + bool isFileUpload(); + bool isFileDownload(); + bool isDccChat(); + bool isFileTransfer(){ return (isFileUpload() || isFileDownload()); }; +#ifdef COMPILE_SSL_SUPPORT + bool isSSL() const { return bIsSSL; }; +#endif +}; + +#endif //_DESCRIPTOR_H_ diff --git a/src/modules/dcc/DccDialog.cpp b/src/modules/dcc/DccDialog.cpp new file mode 100644 index 000000000..9cc68b906 --- /dev/null +++ b/src/modules/dcc/DccDialog.cpp @@ -0,0 +1,226 @@ +//============================================================================= +// +// File : DccDialog.cpp +// Creation date : Tue Sep 19 09 2000 15:23:12 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "DccDialog.h" + +#include "KviLocale.h" +#include "KviIconManager.h" +#include "KviApplication.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DccDialog::DccDialog(DccBroker * br,DccDescriptor * dcc) +{ + m_pDescriptor = dcc; + m_pBroker = br; +} + +DccDialog::~DccDialog() +{ + if(m_pDescriptor)delete m_pDescriptor; + m_pDescriptor = 0; + m_pBroker->unregisterDccBox(this); +} + +void DccDialog::forgetDescriptor() +{ + m_pDescriptor = 0; +} + +DccAcceptDialog::DccAcceptDialog(DccBroker * br,DccDescriptor * dcc,const QString &text,const QString &capt) +: QWidget(0), DccDialog(br,dcc) +{ + setObjectName("dcc_accept_box"); + //QVBoxLayout * vb = new QVBoxLayout(this,4,4); + QVBoxLayout * vb = new QVBoxLayout(this); + vb->setMargin(4); + vb->setSpacing(4); + QLabel * l = new QLabel(text,this); + l->setWordWrap(true); + vb->addWidget(l); + + //QHBoxLayout *hb = new QHBoxLayout(4); + QHBoxLayout *hb = new QHBoxLayout(); + hb->setSpacing(4); + vb->addLayout(hb,Qt::AlignCenter); + QPushButton * btn = new QPushButton(__tr2qs_ctx("&Accept","dcc"),this); + btn->setDefault(true); + //btn->setFocus(); + hb->addWidget(btn); + connect(btn,SIGNAL(clicked()),this,SLOT(acceptClicked())); + btn = new QPushButton(__tr2qs_ctx("&Reject","dcc"),this); + connect(btn,SIGNAL(clicked()),this,SLOT(rejectClicked())); + hb->addWidget(btn); + + setWindowIcon(QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DCCMSG)))); + setWindowTitle(capt); + + l->activateWindow(); + l->setFocus(); +} + +DccAcceptDialog::~DccAcceptDialog() +{ +} + +void DccAcceptDialog::acceptClicked() +{ + hide(); + emit accepted(this,m_pDescriptor); + this->deleteLater(); + //g_pApp->collectGarbage(this); +} + +void DccAcceptDialog::rejectClicked() +{ + hide(); + emit rejected(this,m_pDescriptor); + this->deleteLater(); + //g_pApp->collectGarbage(this); +} + +void DccAcceptDialog::closeEvent(QCloseEvent *e) +{ + hide(); + e->ignore(); + emit rejected(this,m_pDescriptor); + this->deleteLater(); + //g_pApp->collectGarbage(this); +} + +void DccAcceptDialog::showEvent(QShowEvent *e) +{ + QRect rect = g_pApp->desktop()->screenGeometry(g_pApp->desktop()->primaryScreen()); + move((rect.width() - width())/2,(rect.height() - height())/2); + QWidget::showEvent(e); +} + + +DccRenameDialog::DccRenameDialog(DccBroker * br,DccDescriptor * dcc,const QString &text,bool bDisableResume) +: QWidget(0), DccDialog(br,dcc) +{ + setObjectName("dcc_rename_box"); + //QVBoxLayout * vb = new QVBoxLayout(this,4,4); + QVBoxLayout * vb = new QVBoxLayout(this); + vb->setMargin(4); + vb->setSpacing(4); + QLabel * l = new QLabel(text,this); + l->setWordWrap(true); + vb->addWidget(l); + + //QHBoxLayout *hb = new QHBoxLayout(4); + QHBoxLayout *hb = new QHBoxLayout(); + hb->setSpacing(4); + vb->addLayout(hb,Qt::AlignCenter); + + QPushButton * btn = new QPushButton(__tr2qs_ctx("&Rename","dcc"),this); + hb->addWidget(btn); + connect(btn,SIGNAL(clicked()),this,SLOT(renameClicked())); + + btn = new QPushButton(__tr2qs_ctx("Over&write","dcc"),this); + hb->addWidget(btn); + connect(btn,SIGNAL(clicked()),this,SLOT(overwriteClicked())); + + btn = new QPushButton(__tr2qs_ctx("Re&sume","dcc"),this); + hb->addWidget(btn); + connect(btn,SIGNAL(clicked()),this,SLOT(resumeClicked())); + if(bDisableResume)btn->setEnabled(false); + + btn = new QPushButton(__tr2qs_ctx("Cancel","dcc"),this); + hb->addWidget(btn); + connect(btn,SIGNAL(clicked()),this,SLOT(cancelClicked())); + btn->setDefault(true); + //btn->setFocus(); + + setWindowIcon(QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DCCMSG)))); + setWindowTitle(__tr2qs_ctx("File Already Exists - KVIrc","dcc")); +} + +DccRenameDialog::~DccRenameDialog() +{ +} + +void DccRenameDialog::closeEvent(QCloseEvent *e) +{ + hide(); + e->ignore(); + if(m_pDescriptor) + { + emit cancelSelected(this,m_pDescriptor); + //g_pApp->collectGarbage(this); + this->deleteLater(); + } +} + +void DccRenameDialog::showEvent(QShowEvent *e) +{ + move((g_pApp->desktop()->width() - width()) >> 1, + (g_pApp->desktop()->height() - height()) >> 1); + QWidget::showEvent(e); +} + +void DccRenameDialog::renameClicked() +{ + hide(); + emit renameSelected(this,m_pDescriptor); + //g_pApp->collectGarbage(this); + this->deleteLater(); +} + +void DccRenameDialog::overwriteClicked() +{ + hide(); + emit overwriteSelected(this,m_pDescriptor); + //g_pApp->collectGarbage(this); + this->deleteLater(); +} + +void DccRenameDialog::resumeClicked() +{ + hide(); + m_pDescriptor->bResume = true; + emit overwriteSelected(this,m_pDescriptor); + this->deleteLater(); + //g_pApp->collectGarbage(this); +} + +void DccRenameDialog::cancelClicked() +{ + hide(); + emit cancelSelected(this,m_pDescriptor); + this->deleteLater(); + //g_pApp->collectGarbage(this); +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_DccDialog.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/dcc/DccDialog.h b/src/modules/dcc/DccDialog.h new file mode 100644 index 000000000..546c789a4 --- /dev/null +++ b/src/modules/dcc/DccDialog.h @@ -0,0 +1,83 @@ +#ifndef _DIALOGS_H_ +#define _DIALOGS_H_ +//============================================================================= +// +// File : DccDialog.h +// Creation date : Tue Sep 19 09 2000 15:17:22 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "DccBroker.h" + +#include "KviFileDialog.h" + +#include + +class DccDialog +{ +protected: + DccDescriptor * m_pDescriptor; + DccBroker * m_pBroker; +public: + DccDialog(DccBroker * br,DccDescriptor * dcc); + virtual ~DccDialog(); +public: + virtual void forgetDescriptor(); +}; + + +class DccAcceptDialog : public QWidget, public DccDialog +{ + Q_OBJECT +public: + DccAcceptDialog(DccBroker * br,DccDescriptor * dcc,const QString &text,const QString &capt); + ~DccAcceptDialog(); +protected: + virtual void closeEvent(QCloseEvent *e); + virtual void showEvent(QShowEvent *e); +private slots: + void acceptClicked(); + void rejectClicked(); +signals: + void accepted(DccDialog *,DccDescriptor *); + void rejected(DccDialog *,DccDescriptor *); +}; + +class DccRenameDialog : public QWidget, public DccDialog +{ + Q_OBJECT +public: + DccRenameDialog(DccBroker * br,DccDescriptor * dcc,const QString &text,bool bDisableResume); + ~DccRenameDialog(); +protected: + virtual void closeEvent(QCloseEvent *e); + virtual void showEvent(QShowEvent *e); +private slots: + void renameClicked(); + void overwriteClicked(); + void resumeClicked(); + void cancelClicked(); +signals: + void overwriteSelected(DccDialog *,DccDescriptor *); + void renameSelected(DccDialog *,DccDescriptor *); + void cancelSelected(DccDialog *,DccDescriptor *); +}; + +#endif diff --git a/src/modules/dcc/DccFileTransfer.cpp b/src/modules/dcc/DccFileTransfer.cpp new file mode 100644 index 000000000..4fd0ed4a2 --- /dev/null +++ b/src/modules/dcc/DccFileTransfer.cpp @@ -0,0 +1,2248 @@ +//============================================================================= +// +// File : DccFileTransfer.cpp +// Creation date : Tue Sep 20 09 2000 15:14:14 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#define _KVI_DEBUG_CHECK_RANGE_ + +#include "DccFileTransfer.h" +#include "DccBroker.h" +#include "DccMarshal.h" +#include "DccBroker.h" +#include "DccWindow.h" + +#include "kvi_debug.h" +#include "KviApplication.h" +#include "KviOptions.h" +#include "KviIrcView.h" +#include "KviIconManager.h" +#include "KviLocale.h" +#include "KviError.h" +#include "kvi_out.h" +#include "KviNetUtils.h" +#include "KviConsoleWindow.h" +#include "KviMainWindow.h" +#include "KviMemory.h" +#include "KviMemory.h" +#include "KviThread.h" +#include "KviIrcSocket.h" +#include "KviMediaManager.h" +#include "kvi_socket.h" +#include "KviKvsEventTriggers.h" +#include "KviParameterList.h" +#include "KviIrcConnection.h" +#include "KviIrcConnectionUserInfo.h" +#include "KviIrcServerParser.h" +#include "KviKvsScript.h" + +#ifdef COMPILE_ON_WINDOWS + // Ugly Windoze compiler... + #include "DccDialog.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS 3000 +#define INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS 3 + +// This limit, when multiplied by INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS +// must fit in 31 bits (0x7fffffff)! (because of data size limits) +#define MAX_DCC_BANDWIDTH_LIMIT 0x1fffffff + +// FIXME: The events OnDCCConnect etc are in wrong places here...! + +extern DccBroker * g_pDccBroker; + +extern KVIRC_API KviMediaManager * g_pMediaManager; // KviApplication.cpp + + +static KviPointerList * g_pDccFileTransfers = 0; +static QPixmap * g_pDccFileTransferIcon = 0; + +//#warning "The events that have a KviCString data pointer should become real classes, that take care of deleting the data pointer!" +//#warning "Otherwise, when left undispatched we will be leaking memory (event class destroyed but not the data ptr)" + +DccRecvThread::DccRecvThread(QObject * par,kvi_socket_t fd,KviDccRecvThreadOptions * opt) +: DccThread(par,fd) +{ + m_pOpt = opt; + m_uAverageSpeed = 0; + m_uInstantSpeed = 0; + m_uFilePosition = 0; + + m_uTotalReceivedBytes = 0; + m_uInstantReceivedBytes = 0; + m_pFile = 0; + m_pTimeInterval = new KviMSecTimeInterval(); + m_uStartTime = 0; + m_uInstantSpeedInterval = 0; +} + +DccRecvThread::~DccRecvThread() +{ + if(m_pOpt)delete m_pOpt; + if(m_pFile)delete m_pFile; + delete m_pTimeInterval; +} + +bool DccRecvThread::sendAck(int filePos) +{ + quint32 size = htonl(filePos & 0xffffffff); + int iRet=0; +#ifdef COMPILE_SSL_SUPPORT + if(m_pSSL) + { + iRet = m_pSSL->write((char*)(&size),4); + } else { +#endif + iRet = kvi_socket_send(m_fd,(void *)(&size),4); +#ifdef COMPILE_SSL_SUPPORT + } +#endif + + if(iRet != 4) + { + postErrorEvent(KviError::AcknowledgeError); + return false; + } + return true; +} + +void DccRecvThread::updateStats() +{ + m_uInstantSpeedInterval += m_pTimeInterval->mark(); + unsigned long uCurTime = m_pTimeInterval->secondsCounter(); + + m_pMutex->lock(); + unsigned long uElapsedTime = uCurTime - m_uStartTime; + if(uElapsedTime < 1)uElapsedTime = 1; + + m_uFilePosition = m_pFile->pos(); + m_uAverageSpeed = m_uTotalReceivedBytes / uElapsedTime; + + if(m_uInstantSpeedInterval > INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS) + { + unsigned int uMSecsOfTheNextInterval = 0; + if(m_uInstantSpeedInterval < (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS + (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS / 2))) + uMSecsOfTheNextInterval = m_uInstantSpeedInterval - INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS; + m_uInstantSpeed = (m_uInstantReceivedBytes * 1000) / m_uInstantSpeedInterval; + m_uInstantReceivedBytes = 0; + m_uInstantSpeedInterval = uMSecsOfTheNextInterval; + } else { + if(uElapsedTime <= INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS) + m_uInstantSpeed = m_uAverageSpeed; + } + m_pMutex->unlock(); +} + +void DccRecvThread::postMessageEvent(const char * m) +{ + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_MESSAGE); + e->setData(new KviCString(m)); + postEvent(parent(),e); +} + +// FIXME: This stuff should be somewhat related to the 1448 bytes TCP basic packet size +#define KVI_DCC_RECV_BLOCK_SIZE 8192 +#define KVI_DCC_RECV_75PERCENTOF_BLOCK_SIZE 6150 + +void DccRecvThread::run() +{ + // take care of sleeping a bit if we can't read stuff + // so we don't hog the CPU too much... + int iFailedSelects = 0; + // take care of sleeping a bit if we get a lot of short reads + // so we don't hog the CPU too much... + int iShortReadQuantifier = 0; + // the algorithm is as follows: + // attempt to read KVI_DCC_RECV_BLOCK_SIZE bytes + // iShortReadQuantifier += ((KVI_DCC_RECV_75PERCENT_OF_BLOCK_SIZE - realReadedBytes) / 42); + // thus we gain points if we read less than 75% of the requested size + // and we loose points otherwise + // there are nearly 24 points per KB + // if(iShortReadQuantifier > 10) + // msleep(iShortReadQuantifier); + // also never sleep more than 500 msecs since it will + // rise our exit latency too much + + m_pTimeInterval->mark(); + m_pMutex->lock(); + m_uStartTime = m_pTimeInterval->secondsCounter(); + m_pMutex->unlock(); + + int iProbableTerminationTime = 0; + + m_pFile = new QFile(QString::fromUtf8(m_pOpt->szFileName.ptr())); + + if(m_pOpt->bResume) + { + if(!m_pFile->open(QIODevice::WriteOnly | QIODevice::Append)) + { + postErrorEvent(KviError::CantOpenFileForAppending); + goto exit_dcc; + } // else pFile is already at end + } else { + if(!m_pFile->open(QIODevice::WriteOnly)) + { + postErrorEvent(KviError::CantOpenFileForWriting); + goto exit_dcc; + } + } + + if(m_pOpt->bSendZeroAck && (!m_pOpt->bNoAcks)) + { + if(!sendAck(m_pFile->pos()))goto exit_dcc; + } + + for(;;) + { + // Dequeue events + while(KviThreadEvent * e = dequeueEvent()) + { + if(e->id() == KVI_THREAD_EVENT_TERMINATE) + { + delete e; + goto exit_dcc; + } else { + // Other events are senseless to us + delete e; + } + } + + bool bCanRead; + bool bDummy; + + if(kvi_select(m_fd,&bCanRead,&bDummy,15000)) + { + // reset sleep time + + if(bCanRead) + { + iFailedSelects = 0; + + // Read a data block + char buffer[KVI_DCC_RECV_BLOCK_SIZE]; + + m_pMutex->lock(); // FIXME: how to remove this lock ? + unsigned int uMaxPossible = (m_pOpt->uMaxBandwidth < MAX_DCC_BANDWIDTH_LIMIT) ? m_pOpt->uMaxBandwidth * INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS : MAX_DCC_BANDWIDTH_LIMIT * INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS; + m_pMutex->unlock(); + unsigned int uToRead = uMaxPossible > m_uInstantReceivedBytes ? uMaxPossible - m_uInstantReceivedBytes : 0; + if(uToRead > KVI_DCC_RECV_BLOCK_SIZE)uToRead = KVI_DCC_RECV_BLOCK_SIZE; + + if(uToRead > 0) + { + int readLen; +#ifdef COMPILE_SSL_SUPPORT + if(m_pSSL) + { + readLen = m_pSSL->read(buffer,uToRead); + } else { +#endif + readLen = kvi_socket_recv(m_fd,buffer,uToRead); +#ifdef COMPILE_SSL_SUPPORT + } +#endif + + if(readLen > 0) + { + // Readed something useful...write back + if(((uint)(readLen + m_pFile->pos())) > m_pOpt->uTotalFileSize) + { + postMessageEvent(__tr_no_lookup_ctx("WARNING: The peer is sending garbage data past the end of the file","dcc")); + postMessageEvent(__tr_no_lookup_ctx("WARNING: Ignoring data past the declared end of file and closing the connection","dcc")); + + readLen = m_pOpt->uTotalFileSize - m_pFile->pos(); + if(readLen > 0) + { + if(m_pFile->write(buffer,readLen) != readLen) + postErrorEvent(KviError::FileIOError); + } + break; + + } else { + if(m_pFile->write(buffer,readLen) != readLen) + { + postErrorEvent(KviError::FileIOError); + break; + } + } + + // Update stats + m_uTotalReceivedBytes += readLen; + m_uInstantReceivedBytes += readLen; + + updateStats(); + // Now send the ack + if(m_pOpt->bNoAcks) + { + // No acks... + // Interrupt if the whole file has been received + if(m_pOpt->uTotalFileSize > 0) + { + if((quint64)m_pFile->pos() == m_pOpt->uTotalFileSize) + { + // Received the whole file...die + KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS); + postEvent(parent(),e); + break; + } + } + } else { + // Must send the ack... the peer must close the connection + if(!sendAck(m_pFile->pos()))break; + } + + // now take care of short reads + iShortReadQuantifier += ((KVI_DCC_RECV_75PERCENTOF_BLOCK_SIZE - readLen) / 42); + if(iShortReadQuantifier > 10) + { + // we're having short reads.. sleep a while + // but don't allow it to go too high: 0.45 sec is really a lot + if(iShortReadQuantifier > 500) + iShortReadQuantifier = 500; + msleep(iShortReadQuantifier); + } else { + // don't allow it to go too low + if(iShortReadQuantifier < -500) + iShortReadQuantifier = -500; + } + + } else { + updateStats(); + // Read problem... + +#ifdef COMPILE_SSL_SUPPORT + if(m_pSSL) + { + // ssl error....? + switch(m_pSSL->getProtocolError(readLen)) + { + case KviSSL::ZeroReturn: + readLen = 0; + break; + case KviSSL::WantRead: + case KviSSL::WantWrite: + // hmmm... + break; + case KviSSL::SyscallError: + { + int iE = m_pSSL->getLastError(true); + if(iE != 0) + { + raiseSSLError(); + postErrorEvent(KviError::SSLError); + goto exit_dcc; + } + } + break; + case KviSSL::SSLError: + { + raiseSSLError(); + postErrorEvent(KviError::SSLError); + goto exit_dcc; + } + break; + default: + // Raise unknown SSL ERROR + postErrorEvent(KviError::SSLError); + goto exit_dcc; + break; + } + } +#endif + + if(readLen == 0) + { + // read EOF.. + if(((quint64)m_pFile->pos() == m_pOpt->uTotalFileSize) || (m_pOpt->uTotalFileSize == 0)) + { + // success if we got the whole file or if we don't know the file size (we trust the peer) + KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS); + postEvent(parent(),e); + break; + } + } + if(!handleInvalidSocketRead(readLen))break; + } + } else { + updateStats(); + + // reached the bandwidth limit: slow down a bit + if(m_uInstantSpeedInterval < (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS - 100)) + msleep(100); + else if(m_uInstantSpeedInterval < (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS - 20)) + msleep(20); + } + } else { + // Can't read stuff (can just write) + updateStats(); + + // sleep up to 300 msecs (if data arrives...we want low exit latency here) + if(iFailedSelects < 100)iFailedSelects++; + updateStats(); + if(iFailedSelects > 3) + msleep(3 * iFailedSelects); + + if((quint64)m_pFile->pos() == m_pOpt->uTotalFileSize) + { + // Wait for the peer to close the connection + if(iProbableTerminationTime == 0) + { + iProbableTerminationTime = (int)kvi_unixTime(); + m_pFile->flush(); + postMessageEvent(__tr_no_lookup_ctx("Data transfer terminated, waiting 30 seconds for the peer to close the connection...","dcc")); + // FIXME: Close the file ? + } else { + int iDiff = (((int)kvi_unixTime()) - iProbableTerminationTime); + if(iDiff > 30) + { + // success if we got the whole file or if we don't know the file size (we trust the peer) + postMessageEvent(__tr_no_lookup_ctx("Data transfer was terminated 30 seconds ago, closing the connection","dcc")); + KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS); + postEvent(parent(),e); + break; + } + } + } + } + // include the artificial delay if needed + if(m_pOpt->iIdleStepLengthInMSec > 0) + msleep(m_pOpt->iIdleStepLengthInMSec); + } else { + // sleep up to 200 msecs (if data arrives...we want low exit latency here) + if(iFailedSelects < 100)iFailedSelects++; + updateStats(); + if(iFailedSelects > 3) + msleep(2 * iFailedSelects); + } + } + +exit_dcc: + if(m_pFile) + { + m_pFile->close(); + delete m_pFile; + m_pFile = 0; + } + +#ifdef COMPILE_SSL_SUPPORT + if(m_pSSL) + { + KviSSLMaster::freeSSL(m_pSSL); + m_pSSL = 0; + } +#endif + + kvi_socket_close(m_fd); + m_fd = KVI_INVALID_SOCKET; +} + +void DccRecvThread::initGetInfo() +{ + m_pMutex->lock(); +} + +void DccRecvThread::doneGetInfo() +{ + m_pMutex->unlock(); +} + +DccSendThread::DccSendThread(QObject * par,kvi_socket_t fd,KviDccSendThreadOptions * opt) +: DccThread(par,fd) +{ + m_pOpt = opt; + // stats + m_uAverageSpeed = 0; + m_uInstantSpeed = 0; + m_uFilePosition = 0; + m_uTotalSentBytes = 0; + m_pTimeInterval = new KviMSecTimeInterval(); + m_uStartTime = 0; + m_uInstantSpeedInterval = 0; +} + +DccSendThread::~DccSendThread() +{ + if(m_pOpt)delete m_pOpt; + delete m_pTimeInterval; +} + +void DccSendThread::updateStats() +{ + m_uInstantSpeedInterval += m_pTimeInterval->mark(); + + m_pMutex->lock(); + unsigned long uElapsedTime = m_pTimeInterval->secondsCounter() - m_uStartTime; + if(uElapsedTime < 1)uElapsedTime = 1; + + if(m_pOpt->bNoAcks) + { + // There are no acks : the avg bandwidth is based on the sent bytes + m_uAverageSpeed = m_uTotalSentBytes / uElapsedTime; + } else { + // acknowledges : we compute the avg bandwidth based on the acks we receive + m_uAverageSpeed = (m_uAckedBytes - m_pOpt->uStartPosition) / uElapsedTime; + } + + if(m_uInstantSpeedInterval >= INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS) + { + // we often overcount the time interval of 10-20 msecs + // and thus our bandwidth is used less than requested. + // for this reason we try to account the time in excess + // to the next period in order to balance the bandwidth usage. + unsigned long uMSecsOfNextPeriodUsed = 0; + if(m_uInstantSpeedInterval > INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS) + { + if(m_uInstantSpeedInterval < (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS + (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS / 2))) + { + uMSecsOfNextPeriodUsed = m_uInstantSpeedInterval - INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS; + m_uInstantSpeedInterval = INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS; + } + // else we have been delayed for a time comparable to a period + // and thus we can't recover the bandwidth... let it go as it does... + } + m_uInstantSpeed = (m_uInstantSentBytes * 1000) / m_uInstantSpeedInterval; + m_uInstantSpeedInterval = uMSecsOfNextPeriodUsed; + m_uInstantSentBytes = 0; + } else { + if(uElapsedTime <= INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS) + m_uInstantSpeed = m_uAverageSpeed; + } + m_pMutex->unlock(); +} + +union _ack_buffer { + char cAckBuffer[4]; + quint32 i32AckBuffer; +}; + +void DccSendThread::run() +{ + m_pTimeInterval->mark(); + m_pMutex->lock(); + m_uStartTime = m_pTimeInterval->secondsCounter(); + m_pMutex->unlock(); + + m_uTotalSentBytes = 0; + m_uInstantSentBytes = 0; + int iFailedSelects = 0; + _ack_buffer ackbuffer; + int iBytesInAckBuffer = 0; + quint32 uLastAck = 0; + quint64 uTotLastAck = 0; + bool bAckHack = false; + int iAckHackRounds = 0; + + if(m_pOpt->iPacketSize < 32)m_pOpt->iPacketSize = 32; + char * buffer = (char *)KviMemory::allocate(m_pOpt->iPacketSize * sizeof(char)); + + QFile * pFile = new QFile(QString::fromUtf8(m_pOpt->szFileName.ptr())); + + if(!pFile->open(QIODevice::ReadOnly)) + { + postErrorEvent(KviError::CantOpenFileForReading); + goto exit_dcc; + } + + if(pFile->size() < 1) + { + postErrorEvent(KviError::CantSendAZeroSizeFile); + goto exit_dcc; + } + + if(pFile->size() >= 0xffffffff) + { + //dcc acks support only files up to 4GiB + bAckHack=true; + } + + if(m_pOpt->uStartPosition > 0) + { + // seek + if(!(pFile->seek(m_pOpt->uStartPosition))) + { + postErrorEvent(KviError::FileIOError); + goto exit_dcc; + } + } + + uLastAck = m_pOpt->uStartPosition; + + for(;;) + { + // Dequeue events + while(KviThreadEvent * e = dequeueEvent()) + { + if(e->id() == KVI_THREAD_EVENT_TERMINATE) + { + delete e; + goto exit_dcc; + } else { + // Other events are senseless to us + delete e; + } + } + + bool bCanRead; + bool bCanWrite; + + if(kvi_select(m_fd,&bCanRead,&bCanWrite,15000)) + { + // reset the sleep time + iFailedSelects = 0; + if(bCanRead) + { + if(!m_pOpt->bNoAcks) + { + int iAckBytesToRead = 4 - iBytesInAckBuffer; + + int readLen; +#ifdef COMPILE_SSL_SUPPORT + if(m_pSSL) + { + readLen = m_pSSL->read((ackbuffer.cAckBuffer + iBytesInAckBuffer),iAckBytesToRead); + } else { +#endif + readLen = kvi_socket_recv(m_fd,(ackbuffer.cAckBuffer + iBytesInAckBuffer),iAckBytesToRead); +#ifdef COMPILE_SSL_SUPPORT + } +#endif + + if(readLen > 0) + { + iBytesInAckBuffer += readLen; + if(iBytesInAckBuffer == 4) + { + quint32 iNewAck = ntohl(ackbuffer.i32AckBuffer); + if(iNewAck > pFile->pos()) + { + // the peer is drunk or is trying to fool us + postErrorEvent(KviError::AcknowledgeError); + break; + } + if(iNewAck < uLastAck) + { + if(bAckHack) + { + //we reached the 4gb ack limit + iAckHackRounds++; + } else { + // the peer is drunk or is trying to fool us + postErrorEvent(KviError::AcknowledgeError); + break; + } + } + uLastAck = iNewAck; + if(bAckHack) + { + uTotLastAck = (iAckHackRounds*4u*1024u*1024u*1024u) + iNewAck; + } else { + + uTotLastAck = iNewAck; + } + iBytesInAckBuffer = 0; + } + } else { +#ifdef COMPILE_SSL_SUPPORT + if(m_pSSL) + { + // ssl error....? + switch(m_pSSL->getProtocolError(readLen)) + { + case KviSSL::ZeroReturn: + readLen = 0; + break; + case KviSSL::WantRead: + case KviSSL::WantWrite: + // hmmm... + break; + case KviSSL::SyscallError: + { + int iE = m_pSSL->getLastError(true); + if(iE != 0) + { + raiseSSLError(); + postErrorEvent(KviError::SSLError); + goto exit_dcc; + } + } + break; + case KviSSL::SSLError: + { + raiseSSLError(); + postErrorEvent(KviError::SSLError); + goto exit_dcc; + } + break; + default: + // Raise unknown SSL ERROR + postErrorEvent(KviError::SSLError); + goto exit_dcc; + break; + } + } +#endif + + if(!handleInvalidSocketRead(readLen))break; + } + + // update stats + m_pMutex->lock(); // is this really necessary ? + m_uAckedBytes = uTotLastAck; + m_pMutex->unlock(); + + if(uLastAck >= (quint64)pFile->size()) + { + KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS); + postEvent(parent(),e); + break; + } + } else { + // No acknowledges + if(m_pOpt->bIsTdcc) + { + // We expect the remote end to close the connection when the whole file has been sent + if(pFile->atEnd()) + { + int iAck; + int readLen; +#ifdef COMPILE_SSL_SUPPORT + if(m_pSSL) + { + readLen = m_pSSL->read((char*)&iAck,4); + } else { +#endif + readLen = kvi_socket_recv(m_fd,(char*)&iAck,4); +#ifdef COMPILE_SSL_SUPPORT + } +#endif + if(readLen == 0) + { + // done...success + updateStats(); + KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS); + postEvent(parent(),e); + break; + } else { + if(readLen < 0) + { +#ifdef COMPILE_SSL_SUPPORT + if(m_pSSL) + { + // ssl error....? + switch(m_pSSL->getProtocolError(readLen)) + { + case KviSSL::ZeroReturn: + readLen = 0; + break; + case KviSSL::WantRead: + case KviSSL::WantWrite: + // hmmm... + break; + case KviSSL::SyscallError: + { + int iE = m_pSSL->getLastError(true); + if(iE != 0) + { + raiseSSLError(); + postErrorEvent(KviError::SSLError); + goto exit_dcc; + } + } + break; + case KviSSL::SSLError: + { + raiseSSLError(); + postErrorEvent(KviError::SSLError); + goto exit_dcc; + } + break; + default: + // Raise unknown SSL ERROR + postErrorEvent(KviError::SSLError); + goto exit_dcc; + break; + } + } +#endif + + if(!handleInvalidSocketRead(readLen))break; + } else { + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_MESSAGE); + e->setData(new KviCString(__tr2qs_ctx("WARNING: Received data in a DCC TSEND, there should be no acknowledges","dcc"))); + postEvent(parent(),e); + } + } + } + } + } + } + if(bCanWrite) + { + if(!pFile->atEnd()) + { + if(m_pOpt->bFastSend || m_pOpt->bNoAcks || (uLastAck == (quint64)pFile->pos())) + { + // maximum readable size + qint64 toRead = pFile->size() - pFile->pos(); + // the max number of bytes we can send in this interval (bandwidth limit) + m_pMutex->lock(); // FIXME: how to remove this lock ? + uint uMaxPossible = m_pOpt->uMaxBandwidth < MAX_DCC_BANDWIDTH_LIMIT ? m_pOpt->uMaxBandwidth * INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS : MAX_DCC_BANDWIDTH_LIMIT * INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS; + m_pMutex->unlock(); + if(uMaxPossible < m_uInstantSentBytes)toRead = 0; // already sent too much! + else { + uMaxPossible -= m_uInstantSentBytes; + if(toRead > uMaxPossible)toRead = uMaxPossible; + } + // limit to packet size + if(toRead > m_pOpt->iPacketSize)toRead = m_pOpt->iPacketSize; + + int written = 0; + if(toRead > 0) + { + // read data + int readed = pFile->read(buffer,toRead); + if(readed < toRead) + { + postErrorEvent(KviError::FileIOError); + break; + } + // send it out + +#ifdef COMPILE_SSL_SUPPORT + if(m_pSSL) + { + written = m_pSSL->write(buffer,toRead); + } else { +#endif + written = kvi_socket_send(m_fd,buffer,toRead); +#ifdef COMPILE_SSL_SUPPORT + } +#endif + + if(written < toRead) + { + if(written < 0) + { +#ifdef COMPILE_SSL_SUPPORT + if(m_pSSL) + { + // ops...might be an SSL error + switch(m_pSSL->getProtocolError(written)) + { + case KviSSL::WantWrite: + case KviSSL::WantRead: + // Async continue... + goto handle_system_error; + break; + case KviSSL::SyscallError: + if(written == 0) + { + raiseSSLError(); + postErrorEvent(KviError::RemoteEndClosedConnection); + goto exit_dcc; + } else { + int iSSLErr = m_pSSL->getLastError(true); + if(iSSLErr != 0) + { + raiseSSLError(); + postErrorEvent(KviError::SSLError); + goto exit_dcc; + } else { + goto handle_system_error; + } + } + break; + case KviSSL::SSLError: + raiseSSLError(); + postErrorEvent(KviError::SSLError); + goto exit_dcc; + break; + default: + postErrorEvent(KviError::SSLError); + goto exit_dcc; + break; + } + } +#endif + + // error ? + if(!handleInvalidSocketRead(written))break; + +handle_system_error: + int err = kvi_socket_error(); +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + if((err != EAGAIN) || (err != EINTR) || (err != WSAEWOULDBLOCK)) +#else + if((err != EAGAIN)||(err != EINTR)) +#endif + { + postErrorEvent(KviError::translateSystemError(err)); + goto exit_dcc; + } + + } else { + // seek back to the right position + pFile->seek(pFile->pos() - (toRead - written)); + } + } + } else { + // just nothing to send out in this interval + // sleep a while + if(m_uInstantSpeedInterval < (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS - 100)) + { + msleep(100); + } else if(m_uInstantSpeedInterval < (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS - 20)) + { + msleep(20); + } + } + + m_uTotalSentBytes += written; + m_uInstantSentBytes += written; + m_uFilePosition = pFile->pos(); + updateStats(); + } + } else { + if(m_pOpt->bNoAcks && !m_pOpt->bIsTdcc) + { + // at end of the file in a blind dcc send... + // not in a tdcc: we can close the file... + updateStats(); + KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS); + postEvent(parent(),e); + break; + } else { + // upload finished but we're waiting for the last ack + // sleep a bit: don't lag the kernie too much while waiting + msleep(100); + } + } + } + } else { + // after 2 failed selects start to sleep + if(iFailedSelects > 3) + { + // sleep up to 200 msecs + if(iFailedSelects < 100)iFailedSelects++; + msleep(3 * iFailedSelects); + } else { + iFailedSelects++; + } + } + + // include the artificial delay if needed + if(m_pOpt->iIdleStepLengthInMSec > 0) + { + msleep(m_pOpt->iIdleStepLengthInMSec); + } + } + +exit_dcc: + KviMemory::free(buffer); + pFile->close(); + delete pFile; + pFile = 0; + +#ifdef COMPILE_SSL_SUPPORT + if(m_pSSL) + { + KviSSLMaster::freeSSL(m_pSSL); + m_pSSL = 0; + } +#endif + kvi_socket_close(m_fd); + m_fd = KVI_INVALID_SOCKET; +} + +void DccSendThread::initGetInfo() +{ + m_pMutex->lock(); +} + +void DccSendThread::doneGetInfo() +{ + m_pMutex->unlock(); +} + + +DccFileTransfer::DccFileTransfer(DccDescriptor * dcc) +: KviFileTransfer() +{ + init(); // ensure we're initialized + g_pDccFileTransfers->append(this); + + m_pResumeTimer = 0; + m_pBandwidthDialog = 0; + + KviQString::sprintf(m_szTransferIdString,__tr2qs_ctx("TRANSFER %d","dcc"),id()); + + m_pDescriptor = dcc; + m_pDescriptor->setTransfer(this); + + m_pMarshal = new DccMarshal(this); + + connect(m_pMarshal,SIGNAL(error(int)),this,SLOT(handleMarshalError(int))); + connect(m_pMarshal,SIGNAL(connected()),this,SLOT(connected())); + connect(m_pMarshal,SIGNAL(inProgress()),this,SLOT(connectionInProgress())); +#ifdef COMPILE_SSL_SUPPORT + connect(m_pMarshal,SIGNAL(startingSSLHandshake()),this,SLOT(startingSSLHandshake())); + connect(m_pMarshal,SIGNAL(sslError(const char *)),this,SLOT(sslError(const char *))); +#endif + + m_szDccType = dcc->bRecvFile ? "RECV" : "SEND"; + if(dcc->bIsTdcc) m_szDccType.prepend("T"); +#ifdef COMPILE_SSL_SUPPORT + if(dcc->bIsSSL) m_szDccType.prepend("S"); +#endif + m_pSlaveRecvThread = 0; + m_pSlaveSendThread = 0; + + m_tTransferStartTime = 0; + m_tTransferEndTime = 0; + + m_szStatusString = __tr2qs_ctx("Setting up the connection","dcc"); + m_eGeneralStatus = Connecting; + + bool bOk; + m_uTotalFileSize = dcc->bRecvFile ? dcc->szFileSize.toULongLong(&bOk) : dcc->szLocalFileSize.toULongLong(&bOk); + if(!bOk)m_uTotalFileSize = 0; + + if(m_pDescriptor->bRecvFile) + m_uMaxBandwidth = KVI_OPTION_BOOL(KviOption_boolLimitDccRecvSpeed) ? KVI_OPTION_UINT(KviOption_uintMaxDccRecvSpeed) : MAX_DCC_BANDWIDTH_LIMIT; + else + m_uMaxBandwidth = KVI_OPTION_BOOL(KviOption_boolLimitDccSendSpeed) ? KVI_OPTION_UINT(KviOption_uintMaxDccSendSpeed) : MAX_DCC_BANDWIDTH_LIMIT; + + startConnection(); +} + +DccFileTransfer::~DccFileTransfer() +{ + g_pDccFileTransfers->removeRef(this); + + if(m_pResumeTimer)delete m_pResumeTimer; + if(m_pBandwidthDialog)delete m_pBandwidthDialog; + + if(m_pSlaveRecvThread) + { + m_pSlaveRecvThread->terminate(); + delete m_pSlaveRecvThread; + m_pSlaveRecvThread = 0; + } + + if(m_pSlaveSendThread) + { + m_pSlaveSendThread->terminate(); + delete m_pSlaveSendThread; + m_pSlaveSendThread = 0; + } + + KviThreadManager::killPendingEvents(this); + + delete m_pDescriptor; + delete m_pMarshal; +} + +void DccFileTransfer::bandwidthDialogDestroyed() +{ + m_pBandwidthDialog = 0; +} + +KviWindow * DccFileTransfer::eventWindow() +{ + KviWindow *w = transferWindow(); + if(w)return w; + return m_pDescriptor->console(); +} + +void DccFileTransfer::startConnection() +{ + if(!(m_pDescriptor->bActive)) + { + // PASSIVE CONNECTION + m_szStatusString = __tr2qs_ctx("Attempting a passive DCC %1 connection","dcc").arg(m_szDccType.ptr()); + outputAndLog(m_szStatusString); + } else { + // ACTIVE CONNECTION + m_szStatusString = __tr2qs_ctx("Attempting an active DCC %1 connection","dcc").arg(m_szDccType.ptr()); + outputAndLog(m_szStatusString); + } + + + if(m_pDescriptor->bResume && m_pDescriptor->bRecvFile) + { + QString fName; + KviIrcServerParser::encodeCtcpParameter(m_pDescriptor->szFileName.toUtf8().data(),fName); + if(m_pDescriptor->isZeroPortRequest()) + { + m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC RESUME %s %s %s %s%c", + m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(), + 0x01, + m_pDescriptor->console()->connection()->encodeText(fName).data(), + m_pDescriptor->szPort.toUtf8().data(), + m_pDescriptor->szLocalFileSize.toUtf8().data(), + m_pDescriptor->zeroPortRequestTag(),0x01); + } else { + m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC RESUME %s %s %s%c", + m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(), + 0x01, + m_pDescriptor->console()->connection()->encodeText(fName).data(), + m_pDescriptor->szPort.toUtf8().data(), + m_pDescriptor->szLocalFileSize.toUtf8().data(),0x01); + } + m_szStatusString = __tr2qs_ctx("Sent DCC RESUME request to %1, waiting for ACCEPT","dcc").arg(m_pDescriptor->szNick); + outputAndLog(m_szStatusString); + + // setup the resume timer: we don't want to wait forever + + if(KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) < 5) + KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) = 5; + + if(m_pResumeTimer)delete m_pResumeTimer; + m_pResumeTimer = new QTimer(this); + connect(m_pResumeTimer,SIGNAL(timeout()),this,SLOT(resumeTimedOut())); + m_pResumeTimer->setInterval(KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) * 1000); + m_pResumeTimer->setSingleShot(true); + m_pResumeTimer->start(); + } else { + listenOrConnect(); + } + + displayUpdate(); +} + +void DccFileTransfer::listenOrConnect() +{ + if(!(m_pDescriptor->bActive)) + { +#ifdef COMPILE_SSL_SUPPORT + KviError::Code eError = m_pMarshal->dccListen(m_pDescriptor->szListenIp,m_pDescriptor->szListenPort,m_pDescriptor->bDoTimeout,m_pDescriptor->bIsSSL); +#else + KviError::Code eError = m_pMarshal->dccListen(m_pDescriptor->szListenIp,m_pDescriptor->szListenPort,m_pDescriptor->bDoTimeout); +#endif + if(eError != KviError::Success) + handleMarshalError(eError); + } else { +#ifdef COMPILE_SSL_SUPPORT + KviError::Code eError = m_pMarshal->dccConnect(m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data(),m_pDescriptor->bDoTimeout,m_pDescriptor->bIsSSL); +#else + KviError::Code eError = m_pMarshal->dccConnect(m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data(),m_pDescriptor->bDoTimeout); +#endif + if(eError != KviError::Success) + handleMarshalError(eError); + } + + displayUpdate(); +} + +void DccFileTransfer::resumeTimedOut() +{ + if(m_pResumeTimer) + { + delete m_pResumeTimer; + m_pResumeTimer = 0; + } + handleMarshalError(KviError::ConnectionTimedOut); +} + +KviWindow * DccFileTransfer::dccMarshalOutputWindow() +{ + return transferWindow(); +} + +const char * DccFileTransfer::dccMarshalOutputContextString() +{ + return m_szTransferIdString.toUtf8().data(); +} + +QString DccFileTransfer::localFileName() +{ + return m_pDescriptor->szLocalFileName; +} + +void DccFileTransfer::abort() +{ + if(m_pSlaveRecvThread)m_pSlaveRecvThread->terminate(); + if(m_pSlaveSendThread)m_pSlaveSendThread->terminate(); + if(m_pMarshal)m_pMarshal->abort(); + + if(m_pDescriptor->bRecvFile) + g_pApp->fileDownloadTerminated(false,m_pDescriptor->szFileName.toUtf8().data(),m_pDescriptor->szLocalFileName.toUtf8().data(),m_pDescriptor->szNick.toUtf8().data(),__tr_ctx("Aborted","dcc")); + + QString tmp; + + if(m_pSlaveRecvThread)tmp.setNum(m_pSlaveRecvThread->receivedBytes()); + else if(m_pSlaveSendThread)tmp.setNum(m_pSlaveSendThread->sentBytes()); + else tmp = '0'; + + m_eGeneralStatus = Failure; + m_tTransferEndTime = kvi_unixTime(); + m_szStatusString = __tr2qs_ctx("Transfer failed: ","dcc"); + m_szStatusString += __tr2qs_ctx("Aborted","dcc"); + + KVS_TRIGGER_EVENT_3(KviEvent_OnDCCFileTransferFailed,eventWindow(),QString("Aborted by user"),tmp,m_pDescriptor->idString()); + + outputAndLog(KVI_OUT_DCCERROR,m_szStatusString); + displayUpdate(); +} + +void DccFileTransfer::fillContextPopup(KviTalPopupMenu * m) +{ + m->insertItem(__tr2qs_ctx("Configure Bandwidth...","dcc"),this,SLOT(configureBandwidth())); + m->insertSeparator(); + m->insertItem(__tr2qs_ctx("Resend DCC","dcc"),this,SLOT(retryDCC())); + m->insertItem(__tr2qs_ctx("Resend TDCC","dcc"),this,SLOT(retryTDCC())); + m->insertItem(__tr2qs_ctx("Resend RevDCC","dcc"),this,SLOT(retryRevDCC())); + int id = m->insertItem(__tr2qs_ctx("Abort","dcc"),this,SLOT(abort())); + if(!active())m->setItemEnabled(id,false); +} + +void DccFileTransfer::configureBandwidth() +{ + if(m_pBandwidthDialog)return; + m_pBandwidthDialog = new DccFileTransferBandwidthDialog(g_pFrame,this); + connect(m_pBandwidthDialog,SIGNAL(destroyed()),this,SLOT(bandwidthDialogDestroyed())); + m_pBandwidthDialog->setModal(true); + m_pBandwidthDialog->show(); +} + +void DccFileTransfer::retryDCC() +{ + abort(); + QString szRemoteNick = m_pDescriptor->remoteNick(); + QString szFileName = m_pDescriptor->localFileName(); + QString szId = m_pDescriptor->idString(); + KviQString::escapeKvs(&szRemoteNick, KviQString::EscapeSpace); + KviQString::escapeKvs(&szFileName, KviQString::EscapeSpace); + + QString szCommand = "dcc.send -r=$console($dcc.irccontext(" + szId + ")) " + szRemoteNick + " " + szFileName; + KviKvsScript::run(szCommand,g_pActiveWindow); +} + +void DccFileTransfer::retryTDCC() +{ + abort(); + QString szRemoteNick = m_pDescriptor->remoteNick(); + QString szFileName = m_pDescriptor->localFileName(); + QString szId = m_pDescriptor->idString(); + KviQString::escapeKvs(&szRemoteNick, KviQString::EscapeSpace); + KviQString::escapeKvs(&szFileName, KviQString::EscapeSpace); + + QString szCommand = "dcc.send -r=$console($dcc.irccontext(" + szId + ")) -t " + szRemoteNick + " " + szFileName; + KviKvsScript::run(szCommand,g_pActiveWindow); +} + +void DccFileTransfer::retryRevDCC() +{ + abort(); + QString szRemoteNick = m_pDescriptor->remoteNick(); + QString szFileName = m_pDescriptor->localFileName(); + QString szId = m_pDescriptor->idString(); + KviQString::escapeKvs(&szRemoteNick, KviQString::EscapeSpace); + KviQString::escapeKvs(&szFileName, KviQString::EscapeSpace); + + QString szCommand = "dcc.rsend -z -r=$console($dcc.irccontext(" + szId + ")) " + szRemoteNick + " " + szFileName; + KviKvsScript::run(szCommand,g_pActiveWindow); +} + +void DccFileTransfer::fillStatusString(QString &szBuffer) +{ + switch(m_eGeneralStatus) + { + case Connecting: + szBuffer = "connecting"; + break; + case Transferring: + szBuffer = "transferring"; + break; + case Failure: + szBuffer = "failure"; + break; + case Success: + szBuffer = "success"; + break; + default: + szBuffer = "unknown"; + break; + } +} + +bool DccFileTransfer::active() +{ + return ((m_eGeneralStatus == Connecting) || (m_eGeneralStatus == Transferring)); +} + +int DccFileTransfer::bandwidthLimit() +{ + int iLimit = m_uMaxBandwidth; // we have the cached value anyway... + if(m_pDescriptor->bRecvFile) + { + if(m_pSlaveRecvThread) + { + m_pSlaveRecvThread->initGetInfo(); + iLimit = (int)m_pSlaveRecvThread->bandwidthLimit(); + m_pSlaveRecvThread->doneGetInfo(); + if(iLimit < 0)iLimit = MAX_DCC_BANDWIDTH_LIMIT; + } + } else { + if(m_pSlaveSendThread) + { + m_pSlaveSendThread->initGetInfo(); + iLimit = (int)m_pSlaveSendThread->bandwidthLimit(); + m_pSlaveSendThread->doneGetInfo(); + if(iLimit < 0)iLimit = MAX_DCC_BANDWIDTH_LIMIT; + } + } + return iLimit; +} + +void DccFileTransfer::setBandwidthLimit(int iVal) +{ + if(iVal < 0)iVal = MAX_DCC_BANDWIDTH_LIMIT; + if(iVal > MAX_DCC_BANDWIDTH_LIMIT)iVal = MAX_DCC_BANDWIDTH_LIMIT; + m_uMaxBandwidth = iVal; + if(m_pDescriptor->bRecvFile) + { + if(m_pSlaveRecvThread) + { + m_pSlaveRecvThread->initGetInfo(); + m_pSlaveRecvThread->setBandwidthLimit(iVal); + m_pSlaveRecvThread->doneGetInfo(); + } + } else { + if(m_pSlaveSendThread) + { + m_pSlaveSendThread->initGetInfo(); + m_pSlaveSendThread->setBandwidthLimit(iVal); + m_pSlaveSendThread->doneGetInfo(); + } + } +} + +unsigned int DccFileTransfer::averageSpeed() +{ + unsigned int uAvgBandwidth = 0; + if(m_pDescriptor->bRecvFile) + { + if(m_pSlaveRecvThread) + { + m_pSlaveRecvThread->initGetInfo(); + uAvgBandwidth = m_pSlaveRecvThread->averageSpeed(); + m_pSlaveRecvThread->doneGetInfo(); + } + } else { + if(m_pSlaveSendThread) + { + m_pSlaveSendThread->initGetInfo(); + uAvgBandwidth = m_pSlaveSendThread->averageSpeed(); + m_pSlaveSendThread->doneGetInfo(); + } + } + return uAvgBandwidth; +} + +unsigned int DccFileTransfer::transferredBytes() +{ + unsigned int uTransferred = 0; + if(m_pDescriptor->bRecvFile) + { + if(m_pSlaveRecvThread) + { + m_pSlaveRecvThread->initGetInfo(); + uTransferred = m_pSlaveRecvThread->filePosition(); + m_pSlaveRecvThread->doneGetInfo(); + } + } else { + if(m_pSlaveSendThread) + { + m_pSlaveSendThread->initGetInfo(); + uTransferred = m_pSlaveSendThread->filePosition(); + m_pSlaveSendThread->doneGetInfo(); + } + } + return uTransferred; +} + +void DccFileTransfer::displayPaint(QPainter * p,int column, QRect rect) +{ + int width = rect.width(), height = rect.height(); + QString txt; + bool bIsTerminated = ((m_eGeneralStatus == Success) || (m_eGeneralStatus == Failure)); + + switch(column) + { + case COLUMN_TRANSFERTYPE: + { + if(!g_pDccFileTransferIcon)break; + int xoffset = 0; + int yoffset = 0; + if(m_pDescriptor->bRecvFile)yoffset = 64; + switch(m_eGeneralStatus) + { + case Connecting: xoffset = 0; break; + case Transferring: xoffset = 48; break; + case Success: xoffset = 96; break; + case Failure: xoffset = 144; break; + } + p->drawPixmap(rect.left() + 3,rect.top() + 3,*g_pDccFileTransferIcon,xoffset,yoffset,48,64); + } + break; + case COLUMN_FILEINFO: + { + + QFontMetrics fm(p->font()); + + QString szFrom = __tr2qs_ctx("From: ","dcc"); + QString szTo = __tr2qs_ctx("To: ","dcc"); + + int daW1 = fm.width(szFrom); + int daW2 = fm.width(szTo); + if(daW1 < daW2)daW1 = daW2; + int iLineSpacing = fm.lineSpacing(); + + int iY = rect.top() + 4; + + p->setPen(Qt::black); + + KviCString szRemote(KviCString::Format,"dcc://%s@%s:%s/%s",m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data(), + m_pDescriptor->szFileName.toUtf8().data()); + + p->drawText(rect.left() + 4 + daW1,iY,width - (8 + daW1),height - 8,Qt::AlignTop | Qt::AlignLeft, + m_pDescriptor->bRecvFile ? szRemote.ptr() : m_pDescriptor->szLocalFileName.toUtf8().data()); + iY += iLineSpacing; + + p->drawText(rect.left() + 4 + daW1,iY,width - (8 + daW1),height - 8,Qt::AlignTop | Qt::AlignLeft, + m_pDescriptor->bRecvFile ? m_pDescriptor->szLocalFileName.toUtf8().data() : szRemote.ptr()); + iY += iLineSpacing; + + + p->setPen(Qt::darkGray); + + p->drawText(rect.left() + 4, rect.top() + 4,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,szFrom); + p->drawText(rect.left() + 4, rect.top() + 4 + iLineSpacing,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,szTo); + + + p->setPen(QColor(180,180,200)); + + iLineSpacing += 2; + + p->drawRect(rect.left() + 4, rect.top() + height - (iLineSpacing + 4),width - 8,iLineSpacing); + p->fillRect(rect.left() + 5, rect.top() + height - (iLineSpacing + 3),width - 10,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240)); + + p->setPen(Qt::black); + + p->drawText(rect.left() + 7, rect.top() + height - (iLineSpacing + 4),width - 14,iLineSpacing,Qt::AlignVCenter | Qt::AlignLeft,m_szStatusString); + + } + break; + case COLUMN_PROGRESS: + { + + QFontMetrics fm(p->font()); + + int iW = width - 8; + uint uAvgBandwidth = 0; + uint uInstantSpeed = 0; + quint64 uAckedBytes = 0; + quint64 uTransferred = 0; + int iEta = -1; + + if(m_pDescriptor->bRecvFile) + { + if(m_pSlaveRecvThread) + { + m_pSlaveRecvThread->initGetInfo(); + uAvgBandwidth = m_pSlaveRecvThread->averageSpeed(); + uInstantSpeed = m_pSlaveRecvThread->instantSpeed(); + uTransferred = m_pSlaveRecvThread->filePosition(); + m_pSlaveRecvThread->doneGetInfo(); + } + } else { + if(m_pSlaveSendThread) + { + m_pSlaveSendThread->initGetInfo(); + uAvgBandwidth = m_pSlaveSendThread->averageSpeed(); + uInstantSpeed = m_pSlaveSendThread->instantSpeed(); + uTransferred = m_pSlaveSendThread->filePosition(); + uAckedBytes = m_pSlaveSendThread->ackedBytes(); + m_pSlaveSendThread->doneGetInfo(); + } + } + + p->setPen(bIsTerminated ? Qt::lightGray : QColor(210,210,240)); + p->drawRect(rect.left() + 4, rect.top() + 4,iW,12); + + iW -= 2; + + if(m_uTotalFileSize > 0) + { + if(uAvgBandwidth > 0) + { + quint64 uRemaining = m_uTotalFileSize - uTransferred; + iEta = uRemaining / uAvgBandwidth; + } + + if(!m_pDescriptor->bNoAcks && (uAckedBytes > 0) && (uAckedBytes < uTransferred)) + { + // we are sending a file and are getting acks + + double dPerc1 = (double)(((double)uTransferred) * 100.0) / (double)m_uTotalFileSize; + int iL1 = (int) ((((double)iW) * dPerc1) / 100.0); + double dPerc2 = (double)(((double)uAckedBytes) * 100.0) / (double)m_uTotalFileSize; + int iL2 = (int) ((((double)iW) * dPerc2) / 100.0); + int iW2 = iL1 - iL2; + if(iW2 > 0)p->fillRect(rect.left() + 5 + iL2,rect.top() + 5,iW2,10,bIsTerminated ? QColor(150,130,110) : QColor(220,170,100)); + p->fillRect(rect.left() + 5,rect.top() + 5,iL2,10,bIsTerminated ? QColor(140,110,110) : QColor(200,100,100)); + + txt = QString(__tr2qs_ctx("%1 of %2 (%3%)","dcc")).arg(KviQString::makeSizeReadable(uAckedBytes), KviQString::makeSizeReadable(m_uTotalFileSize)).arg(dPerc2,0,'f',2); + } else { + // we are receiving a file or not sending acks + double dPerc = (double)(((double)uTransferred) * 100.0) / (double)m_uTotalFileSize; + int iL = (int) ((((double)iW) * dPerc) / 100.0); + p->fillRect(rect.left() + 5,rect.top() + 5,iL,10,bIsTerminated ? QColor(140,110,110) : QColor(200,100,100)); + + txt = QString(__tr2qs_ctx("%1 of %2 (%3%)","dcc")).arg(KviQString::makeSizeReadable(uTransferred), KviQString::makeSizeReadable(m_uTotalFileSize)).arg(dPerc,0,'f',2); + } + + } else { + txt = QString(__tr2qs_ctx("%1","dcc")).arg(KviQString::makeSizeReadable(uTransferred)); + } + + p->setPen(Qt::black); + + p->drawText(rect.left() + 4,rect.top() + 19,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,txt); + + int iLeftHalf = (iW - 2) / 2; + int iRightHalf = iW - (iLeftHalf + 1); + int iLineSpacing = fm.lineSpacing() + 2; + + if(!bIsTerminated) + { + txt = __tr2qs_ctx("Spd:","dcc"); + txt += " "; + + QString tmpisp; + KviNetUtils::formatNetworkBandwidthString(tmpisp,uInstantSpeed); + txt += tmpisp; + txt += " ["; + } else { + txt = ""; + } + + txt += __tr2qs_ctx("Avg:","dcc"); + txt += " "; + QString tmpspd; + KviNetUtils::formatNetworkBandwidthString(tmpspd,uAvgBandwidth); + txt += tmpspd; + + if(!bIsTerminated) + { + txt += "]"; + } + + int iDaH = height - (iLineSpacing + 4); + + p->setPen(QColor(180,180,200)); + p->drawRect(rect.left() + 4,rect.top() + iDaH,iLeftHalf,iLineSpacing); + p->fillRect(rect.left() + 5,rect.top() + iDaH + 1,iLeftHalf - 2,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240)); + p->setPen(bIsTerminated ? Qt::darkGray : Qt::black); + p->drawText(rect.left() + 6,rect.top() + iDaH,iLeftHalf - 4,iLineSpacing,Qt::AlignLeft | Qt::AlignVCenter,txt); + + if(bIsTerminated) + { + if((m_tTransferStartTime != 0) && (m_tTransferEndTime != 0)) + { + QString tot = KviTimeUtils::formatTimeInterval(kvi_timeSpan(m_tTransferEndTime,m_tTransferStartTime),KviTimeUtils::NoLeadingEmptyIntervals | KviTimeUtils::NoLeadingZeroes); + txt = "TOT: "; + txt += tot; + } else { + txt = ""; + } + } else { + if(iEta >= 0) + { + QString eta = KviTimeUtils::formatTimeInterval(iEta,KviTimeUtils::NoLeadingEmptyIntervals | KviTimeUtils::NoLeadingZeroes); + txt = "ETA: "; + txt += eta; + } else { + txt = "ETA: ?"; + } + } + + p->setPen(QColor(180,180,200)); + p->drawRect(rect.left() + width - (4 + iRightHalf),rect.top() + iDaH,iRightHalf,iLineSpacing); + p->fillRect(rect.left() + width - (3 + iRightHalf),rect.top() + iDaH + 1,iRightHalf - 2,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240)); + p->setPen(bIsTerminated ? Qt::darkGray : Qt::black); + p->drawText(rect.left() + width - (2 + iRightHalf),rect.top() + iDaH,iRightHalf - 4,iLineSpacing,Qt::AlignLeft | Qt::AlignVCenter,txt); + + } + break; + } + +} + +int DccFileTransfer::displayHeight(int iLineSpacing) +{ + int iH = (iLineSpacing * 3) + 10; + return iH >= 70 ? iH : 70; +} + +QString DccFileTransfer::tipText() +{ + QString s; + + s = QString("").arg(m_szDccType.ptr()).arg(id()); + + s += ""; + s += ""; + s += "
DCC %1 (ID %2)
"; + s += __tr2qs_ctx("Transfer Log","dcc"); + s += "
"; + s += m_szTransferLog; + s += "
"; + + return s; +} + +void DccFileTransfer::init() +{ + if(g_pDccFileTransfers)return; + g_pDccFileTransfers = new KviPointerList; + g_pDccFileTransfers->setAutoDelete(false); + + QPixmap * pix = g_pIconManager->getImage("kvi_dccfiletransfericons.png", false); + if(pix)g_pDccFileTransferIcon = new QPixmap(*pix); + else g_pDccFileTransferIcon = 0; +} + +void DccFileTransfer::done() +{ + if(!g_pDccFileTransfers)return; + while(DccFileTransfer * t = g_pDccFileTransfers->first()) + delete t; + delete g_pDccFileTransfers; + g_pDccFileTransfers = 0; + if(g_pDccFileTransferIcon)delete g_pDccFileTransferIcon; + g_pDccFileTransferIcon = 0; +} + +unsigned int DccFileTransfer::transferCount() +{ + if(!g_pDccFileTransfers)return 0; + return g_pDccFileTransfers->count(); +} + +DccFileTransfer * DccFileTransfer::nonFailedTransferWithLocalFileName(const QString &szLocalFileName) +{ + if(!g_pDccFileTransfers)return 0; + for(DccFileTransfer * t = g_pDccFileTransfers->first();t;t = g_pDccFileTransfers->next()) + { +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + // on windows the file names are case insensitive + if(t->localFileName().toLower() == szLocalFileName.toLower()) +#else + if(t->localFileName() == szLocalFileName) +#endif + { + if(t->m_eGeneralStatus != Failure) + return t; + } + } + return 0; +} + +unsigned int DccFileTransfer::runningTransfersCount() +{ + if(!g_pDccFileTransfers)return 0; + unsigned int cnt = 0; + for(DccFileTransfer * t = g_pDccFileTransfers->first();t;t = g_pDccFileTransfers->next()) + { + if(t->active())cnt++; + } + return cnt; +} + +bool DccFileTransfer::handleResumeAccepted(const char * filename,const char * port,const char * szZeroPortTag) +{ + if(!g_pDccFileTransfers)return false; + + for(DccFileTransfer * t = g_pDccFileTransfers->first();t;t = g_pDccFileTransfers->next()) + { + if(t->resumeAccepted(filename,port,szZeroPortTag))return true; + } + + return false; +} + +bool DccFileTransfer::handleResumeRequest(const char * filename,const char * port,quint64 filePos) +{ + if(!g_pDccFileTransfers) + return false; + + for(DccFileTransfer * t = g_pDccFileTransfers->first();t;t = g_pDccFileTransfers->next()) + { + if(t->doResume(filename,port,filePos)) + return true; + } + + return false; +} + +void DccFileTransfer::outputAndLog(const QString &s) +{ + KviWindow * out = transferWindow(); + addToTransferLog(s); + if(out)out->output(KVI_OUT_DCCMSG,"[%Q]: %Q",&m_szTransferIdString,&s); +} + +void DccFileTransfer::outputAndLog(int msgtype,const QString &s) +{ + KviWindow * out = transferWindow(); + addToTransferLog(s); + if(out)out->output(msgtype,"[%Q]: %Q",&m_szTransferIdString,&s); +} + + +void DccFileTransfer::addToTransferLog(const QString &s) +{ + QDateTime dt = QDateTime::currentDateTime(); + QString ts; + ts.sprintf("[%4d.%2d.%2d %2d:%2d:%2d] ",dt.date().year(),dt.date().month(),dt.date().day(),dt.time().hour(),dt.time().minute(),dt.time().second()); + m_szTransferLog += ts+s; + m_szTransferLog += "
"; +} + +void DccFileTransfer::connectionInProgress() +{ + if(m_pDescriptor->bActive) + { + // ACTIVE CONNECTION +// if((kvi_strEqualCS(m_szDccType.ptr(), "RECV")) || (kvi_strEqualCS(m_szDccType.ptr(),"TRECV"))) +// { +// // FIXME: that's not true!... we're NOT connected here +// if(TRIGGER_EVENT_5PARAM_RETVALUE(KviEvent_OnDCCGetConnected,this,m_pDescriptor->szPort.ptr(),m_pDescriptor->szFileName.ptr(),m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(),m_pDescriptor->szHost.ptr())); +// } else { +// if(TRIGGER_EVENT_5PARAM_RETVALUE(KviEvent_OnDCCSendConnected,this,m_pDescriptor->szPort.ptr(),m_pDescriptor->szFileName.ptr(),m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(),m_pDescriptor->szHost.ptr())); +// } +// + m_szStatusString = __tr2qs_ctx("Contacting host %1 on port %2","dcc").arg(m_pDescriptor->szIp, m_pDescriptor->szPort); + outputAndLog(m_szStatusString); + displayUpdate(); + return; + } + + // PASSIVE CONNECTION + m_szStatusString = __tr2qs_ctx("Listening on interface %1 port %2","dcc").arg(m_pMarshal->localIp(), m_pMarshal->localPort()); + outputAndLog(m_szStatusString); + + if(m_pDescriptor->bSendRequest) + { + QString ip; + if(!m_pDescriptor->szFakeIp.isEmpty()) + { + ip = m_pDescriptor->szFakeIp; + } else { + ip = m_pDescriptor->szListenIp; + + if(KVI_OPTION_BOOL(KviOption_boolDccGuessIpFromServerWhenLocalIsUnroutable)) + { + if(!KviNetUtils::isRoutableIpString(ip)) + { + // try to get the IP that the IRC server can see + if(m_pDescriptor->console()) + { + QString tmp = m_pDescriptor->console()->connection() ? m_pDescriptor->console()->connection()->userInfo()->hostIp() : ""; + if(!tmp.isEmpty()) + { + ip = tmp; + outputAndLog(__tr2qs_ctx("The local IP address is private, determining from IRC server: %1","dcc").arg(ip)); + } else { + outputAndLog(__tr2qs_ctx("The local IP address is private, but unable to determine it from the IRC server","dcc")); + } + } else { + outputAndLog(__tr2qs_ctx("The local IP address is private, but have no IRC server to determine it from","dcc")); + } + } + } + } + + KviCString port = !m_pDescriptor->szFakePort.isEmpty() ? m_pDescriptor->szFakePort : m_pMarshal->localPort(); + //#warning "OPTION FOR SENDING 127.0.0.1 and so on (not an unsigned nuumber)" + struct in_addr a; + if(KviNetUtils::stringIpToBinaryIp(ip,&a))ip.setNum(htonl(a.s_addr)); + + QString tmp = m_pDescriptor->szFileName; + // just to be sure + KviQString::cutToLast(tmp,'/'); + KviQString::cutToLast(tmp,'\\'); + + QString fName; + + // BUG-TO-BUG mIrc compatibility + if(KVI_OPTION_BOOL(KviOption_boolDCCFileTransferReplaceOutgoingSpacesWithUnderscores)) + tmp.replace(" ","_"); + + KviIrcServerParser::encodeCtcpParameter(tmp.toUtf8().data(),fName); + // Zero port requests want DCC SEND as back-request + KviCString szReq; + + if(m_pDescriptor->isZeroPortRequest()) + { + szReq = "SEND"; + if(m_pDescriptor->bIsTdcc) szReq.prepend("T"); +#ifdef COMPILE_SSL_SUPPORT + if(m_pDescriptor->bIsSSL) szReq.prepend("S"); +#endif + m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC %s %s %s %s %s %s%c", + m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(), + 0x01, + m_pDescriptor->console()->connection()->encodeText(szReq.ptr()).data(), + m_pDescriptor->console()->connection()->encodeText(fName).data(), + ip.toUtf8().data(),port.ptr(), + m_pDescriptor->szFileSize.toUtf8().data(),m_pDescriptor->zeroPortRequestTag(),0x01); + } else { + szReq = m_szDccType; + m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC %s %s %s %s %Q%c", + m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(), + 0x01, + m_pDescriptor->console()->connection()->encodeText(szReq.ptr()).data(), + m_pDescriptor->console()->connection()->encodeText(fName).data(), + ip.toUtf8().data(),port.ptr(), + &(m_pDescriptor->szLocalFileSize),0x01); + } + outputAndLog(__tr2qs_ctx("Sent DCC %1 request to %2, waiting for remote client to connect...","dcc").arg(szReq.ptr(), m_pDescriptor->szNick)); + } else { + outputAndLog(__tr2qs_ctx("DCC %1 request not sent, awaiting manual connection","dcc").arg(m_szDccType.ptr())); + } + + KVS_TRIGGER_EVENT_1(KviEvent_OnDCCFileTransferConnectionInProgress,eventWindow(),m_pDescriptor->idString()); + + displayUpdate(); +} + +void DccFileTransfer::startingSSLHandshake() +{ +#ifdef COMPILE_SSL_SUPPORT + outputAndLog(KVI_OUT_SSL,__tr2qs_ctx("Low-level transport connection established","dcc")); + outputAndLog(KVI_OUT_SSL,__tr2qs_ctx("Starting Secure Socket Layer handshake","dcc")); +#endif +} + +void DccFileTransfer::sslError(const char * msg) +{ +#ifdef COMPILE_SSL_SUPPORT + outputAndLog(KVI_OUT_DCCERROR,__tr2qs_ctx("[SSL ERROR]: %1","dcc").arg(msg)); +#endif +} + +bool DccFileTransfer::event(QEvent *e) +{ + if(e->type() == KVI_THREAD_EVENT) + { + switch(((KviThreadEvent *)e)->id()) + { + case KVI_DCC_THREAD_EVENT_ERROR: + { + KviError::Code * pError = ((KviThreadDataEvent *)e)->getData(); + QString szErrorString = KviError::getDescription(*pError); + delete pError; + if(m_pDescriptor->bRecvFile) + g_pApp->fileDownloadTerminated(false,m_pDescriptor->szFileName.toUtf8().data(),m_pDescriptor->szLocalFileName.toUtf8().data(),m_pDescriptor->szNick.toUtf8().data(),szErrorString.toUtf8().data()); + + m_szStatusString = __tr2qs_ctx("Transfer failed: ","dcc"); + m_szStatusString += szErrorString; + m_eGeneralStatus = Failure; + m_tTransferEndTime = kvi_unixTime(); + + KVS_TRIGGER_EVENT_3(KviEvent_OnDCCFileTransferFailed, + eventWindow(), + szErrorString, + (kvs_int_t)(m_pSlaveRecvThread ? m_pSlaveRecvThread->receivedBytes() : m_pSlaveSendThread->sentBytes()), + m_pDescriptor->idString()); + + outputAndLog(KVI_OUT_DCCERROR,m_szStatusString); + displayUpdate(); + return true; + } + break; + case KVI_DCC_THREAD_EVENT_SUCCESS: + { + // FIXME: for >= 3.2.0 change this text to + // File Upload/Download terminated, or something like this + if(KVI_OPTION_BOOL(KviOption_boolNotifyDccSendSuccessInConsole)) + { + KviConsoleWindow *c; + if(!g_pApp->windowExists(m_pDescriptor->console())) c=g_pApp->activeConsole(); + else c=m_pDescriptor->console(); + c->output(KVI_OUT_DCCMSG,__tr2qs_ctx("DCC %s transfer with %Q@%Q:%Q completed: \r![!dbl]play $0\r%s\r","dcc"), + m_pDescriptor->bIsTdcc ? (m_pDescriptor->bRecvFile ? "TRECV" : "TSEND") : (m_pDescriptor->bRecvFile ? "RECV" : "SEND"), + &(m_pDescriptor->szNick),&(m_pDescriptor->szIp),&(m_pDescriptor->szPort), + &(m_pDescriptor->szLocalFileName)); + } + /* + // Also add an optional message to the notifier, unless it is an AVATAR download! + if(KVI_OPTION_BOOL(KviOption_boolNotifiDccDownloadSuccessInNotifier)) + { + QString szMsg; + KviQString::sprintf(szMsg,__tr2qs_ctx("")); + g_pApp->notifierMessage(0,KVI_SMALLICON_DCCMSG,szMsg,KVI_OPTION_UINT(KviOption_uintNotifierAutoHideTime)); + } + */ + if(m_pDescriptor->bRecvFile)g_pApp->fileDownloadTerminated(true,m_pDescriptor->szFileName.toUtf8().data(),m_pDescriptor->szLocalFileName.toUtf8().data(),m_pDescriptor->szNick.toUtf8().data()); + m_szStatusString = __tr2qs_ctx("Transfer completed","dcc"); + outputAndLog(m_szStatusString); + m_eGeneralStatus = Success; + m_tTransferEndTime = kvi_unixTime(); + if (m_pResumeTimer) delete m_pResumeTimer; + + KVS_TRIGGER_EVENT_2(KviEvent_OnDCCFileTransferSuccess, + eventWindow(), + (kvs_int_t)(m_pSlaveRecvThread ? m_pSlaveRecvThread->receivedBytes() : m_pSlaveSendThread->sentBytes()), + m_pDescriptor->idString()); + + displayUpdate(); + + if(KVI_OPTION_BOOL(KviOption_boolAutoCloseDccSendOnSuccess))die(); + return true; + } + break; + case KVI_DCC_THREAD_EVENT_MESSAGE: + { + KviCString * str = ((KviThreadDataEvent *)e)->getData(); + outputAndLog(QString(__tr_no_xgettext_ctx(str->ptr(),"dcc"))); + delete str; + return true; + } + break; + default: + qDebug("Invalid event type %d received",((KviThreadEvent *)e)->id()); + break; + } + } +//#warning "Remove this!" +// if(e->type() == QEvent::Close)qDebug("Close event received"); + return KviFileTransfer::event(e); +} + +void DccFileTransfer::handleMarshalError(KviError::Code eError) +{ + QString szErr = KviError::getDescription(eError); + m_eGeneralStatus = Failure; + m_szStatusString = __tr2qs_ctx("Transfer failed: ","dcc"); + m_szStatusString += szErr; + outputAndLog(m_szStatusString); + KVS_TRIGGER_EVENT_3(KviEvent_OnDCCFileTransferFailed,eventWindow(),szErr,(kvs_int_t)0,m_pDescriptor->idString()); + displayUpdate(); +} + +void DccFileTransfer::connected() +{ + outputAndLog(__tr2qs_ctx("Connected to %1:%2","dcc").arg(m_pMarshal->remoteIp(), m_pMarshal->remotePort())); + outputAndLog(__tr2qs_ctx("Local end is %1:%2","dcc").arg(m_pMarshal->localIp(), m_pMarshal->localPort())); + + m_tTransferStartTime = kvi_unixTime(); + + if(!(m_pDescriptor->bActive)) + { + m_pDescriptor->szIp = m_pMarshal->remoteIp(); + m_pDescriptor->szPort = m_pMarshal->remotePort(); + m_pDescriptor->szHost = m_pMarshal->remoteIp(); + } + + if(m_pDescriptor->bRecvFile) + { + KviDccRecvThreadOptions * o = new KviDccRecvThreadOptions; + o->szFileName = m_pDescriptor->szLocalFileName.toUtf8().data(); + bool bOk; + o->uTotalFileSize = m_pDescriptor->szFileSize.toULongLong(&bOk); + if(!bOk)o->uTotalFileSize = 0; + o->bResume = m_pDescriptor->bResume; + o->iIdleStepLengthInMSec = KVI_OPTION_BOOL(KviOption_boolDccSendForceIdleStep) ? KVI_OPTION_UINT(KviOption_uintDccSendIdleStepInMSec) : 0; + o->bIsTdcc = m_pDescriptor->bIsTdcc; + o->bSendZeroAck = KVI_OPTION_BOOL(KviOption_boolSendZeroAckInDccRecv); + o->bNoAcks = m_pDescriptor->bNoAcks; + o->uMaxBandwidth = m_uMaxBandwidth; + m_pSlaveRecvThread = new DccRecvThread(this,m_pMarshal->releaseSocket(),o); + +#ifdef COMPILE_SSL_SUPPORT + KviSSL * s = m_pMarshal->releaseSSL(); + if(s) + { + m_pSlaveRecvThread->setSSL(s); + } +#endif + m_pSlaveRecvThread->start(); + } else { + KviDccSendThreadOptions * o = new KviDccSendThreadOptions; + o->szFileName = m_pDescriptor->szLocalFileName.toUtf8().data(); + o->bFastSend = KVI_OPTION_BOOL(KviOption_boolUseFastDccSend); + o->iIdleStepLengthInMSec = KVI_OPTION_BOOL(KviOption_boolDccSendForceIdleStep) ? KVI_OPTION_UINT(KviOption_uintDccSendIdleStepInMSec) : 0; + bool bOk; + o->bIsTdcc = m_pDescriptor->bIsTdcc; + o->uStartPosition = m_pDescriptor->szFileSize.toULongLong(&bOk); + if(!bOk) o->uStartPosition = 0; + o->iPacketSize = KVI_OPTION_UINT(KviOption_uintDccSendPacketSize); + if(o->iPacketSize < 32)o->iPacketSize = 32; + o->uMaxBandwidth = m_uMaxBandwidth; + o->bNoAcks = m_pDescriptor->bNoAcks; + m_pSlaveSendThread = new DccSendThread(this,m_pMarshal->releaseSocket(),o); +#ifdef COMPILE_SSL_SUPPORT + KviSSL * s = m_pMarshal->releaseSSL(); + if(s) + { + m_pSlaveSendThread->setSSL(s); + } +#endif + m_pSlaveSendThread->start(); + } + + m_eGeneralStatus = Transferring; + m_szStatusString = __tr2qs_ctx("Transferring data","dcc"); + + KVS_TRIGGER_EVENT_1(KviEvent_OnDCCFileTransferBegin,eventWindow(),m_pDescriptor->idString()); + + outputAndLog(m_szStatusString); + displayUpdate(); +} + +bool DccFileTransfer::resumeAccepted(const char *filename,const char *port,const char *szZeroPortTag) +{ + if(!(kvi_strEqualCI(filename,m_pDescriptor->szFileName.toUtf8().data()) || KVI_OPTION_BOOL(KviOption_boolAcceptBrokenFileNameDccResumeRequests))) + return false; + + if(!(kvi_strEqualCI(port,m_pDescriptor->szPort.toUtf8().data()) && + (!m_pSlaveRecvThread) && m_pDescriptor->bResume && m_pDescriptor->bRecvFile && m_pResumeTimer)) + return false; + + if(kvi_strEqualCI(port,"0")) + { + if(!kvi_strEqualCI(szZeroPortTag,m_pDescriptor->zeroPortRequestTag())) + return false; + } + + delete m_pResumeTimer; + m_pResumeTimer = 0; + + outputAndLog(__tr2qs_ctx("RESUME accepted, transfer will begin at position %1","dcc").arg(m_pDescriptor->szLocalFileSize)); + + listenOrConnect(); + + /* + int ret = m_pMarshal->dccConnect(m_pDescriptor->szIp.toUtf8().data(), + m_pDescriptor->szPort.toUtf8().data(),m_pDescriptor->bDoTimeout); + + if(ret != KviError::Success)handleMarshalError(ret); + else { + m_szStatusString = __tr2qs_ctx("Contacting host %1 on port %2","dcc").arg(m_pDescriptor->szIp, m_pDescriptor->szPort); + outputAndLog(m_szStatusString); + displayUpdate(); + } + */ + + return true; +} + +bool DccFileTransfer::doResume(const char * filename,const char * port,quint64 filePos) +{ + if(m_pSlaveRecvThread) + return false; // we're already receiving stuff... + if(m_pSlaveSendThread) + return false; // we're already sending stuff... + + if(m_pDescriptor->bRecvFile) + return false; // we're receiving... can't resume anything + + bool bFileNameMatches = KviQString::equalCI(filename,m_pDescriptor->szFileName); + bool bPortMatches = KviQString::equalCI(port,m_pMarshal->dccPort()); + + if(!bPortMatches) + { + // port doesn't match + if(!bFileNameMatches) + return false; // neither filename nor port match + + if(!KVI_OPTION_BOOL(KviOption_boolAcceptMismatchedPortDccResumeRequests)) + return false; + + // hmm.. try to accept a mismatched port request + + if(_OUTPUT_VERBOSE) + outputAndLog(KVI_OUT_DCCMSG,__tr2qs_ctx("Processing RESUME request with mismatched port (%1)","dcc").arg(port)); + } + + // port matches + + if(!bFileNameMatches) + { + // bad file name + if(!bPortMatches) + return false; // neither filename nor port match + + // port matches (this is very likely to be the right transfer) + + if(!KVI_OPTION_BOOL(KviOption_boolAcceptBrokenFileNameDccResumeRequests)) + { + if(_OUTPUT_VERBOSE) + outputAndLog( + KVI_OUT_DCCMSG, + __tr2qs_ctx("Invalid RESUME request: Invalid file name (got '%1' but should be '%2')","dcc") + .arg(filename) + .arg(m_pDescriptor->szFileName) + ); + return false; // bad file name + } + + if(_OUTPUT_VERBOSE) + outputAndLog(KVI_OUT_DCCMSG,__tr2qs_ctx("Processing RESUME request with broken filename (%1)","dcc").arg(filename)); + } + + bool bOk; + quint64 iLocalFileSize = m_pDescriptor->szLocalFileSize.toULongLong(&bOk); + + if(!bOk) + { + // ops...internal error + outputAndLog(KVI_OUT_DCCERROR,__tr2qs_ctx("Internal error in RESUME request","dcc")); + return false; + } + + if(iLocalFileSize <= filePos) + { + outputAndLog(KVI_OUT_DCCERROR,__tr2qs_ctx("Invalid RESUME request: Position %1 is larger than file size","dcc").arg(filePos)); + return false; + } + + outputAndLog(KVI_OUT_DCCERROR,__tr2qs_ctx("Accepting RESUME request, transfer will begin at position %1","dcc").arg(filePos)); + + m_pDescriptor->szFileSize.setNum(filePos); + + KviCString szBuffy; + KviIrcServerParser::encodeCtcpParameter(filename,szBuffy); + + m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC ACCEPT %s %s %u%c", + m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(), + 0x01, + m_pDescriptor->console()->connection()->encodeText(szBuffy.ptr()).data(), + port,filePos,0x01 + ); + + return true; +} + +DccThread * DccFileTransfer::getSlaveThread() +{ + if(m_pDescriptor->bRecvFile) + { + return m_pSlaveRecvThread; + } else { + return m_pSlaveSendThread; + } +} + + +DccFileTransferBandwidthDialog::DccFileTransferBandwidthDialog(QWidget * pParent,DccFileTransfer * t) +: QDialog(pParent) +{ + QGridLayout * g = new QGridLayout(this); + + m_pTransfer = t; + int iVal = m_pTransfer->bandwidthLimit(); + + QString szText = __tr2qs_ctx("Configure bandwidth for DCC transfer %1","dcc").arg(t->id()); + setWindowTitle(szText); + + szText = t->isFileUpload() ? __tr2qs_ctx("Limit upload bandwidth to","dcc") : __tr2qs_ctx("Limit download bandwidth to","dcc"); + + m_pEnableLimitCheck = new QCheckBox(szText,this); + g->addWidget(m_pEnableLimitCheck,0,0); + + m_pEnableLimitCheck->setChecked((iVal >= 0) && (iVal < MAX_DCC_BANDWIDTH_LIMIT)); + + m_pLimitBox = new QSpinBox(this); + m_pLimitBox->setMinimum(0); + m_pLimitBox->setMaximum(MAX_DCC_BANDWIDTH_LIMIT-1); + m_pLimitBox->setSingleStep(1); + + m_pLimitBox->setEnabled((iVal >= 0) && (iVal < MAX_DCC_BANDWIDTH_LIMIT)); + connect(m_pEnableLimitCheck,SIGNAL(toggled(bool)),m_pLimitBox,SLOT(setEnabled(bool))); + g->addWidget(m_pLimitBox,0,1,1,2); + + szText = " "; + szText += __tr2qs_ctx("bytes/sec","dcc"); + m_pLimitBox->setSuffix(szText); + m_pLimitBox->setValue(iVal < MAX_DCC_BANDWIDTH_LIMIT ? iVal : 0); + + QPushButton * pb = new QPushButton(__tr2qs_ctx("OK","dcc"),this); + connect(pb,SIGNAL(clicked()),this,SLOT(okClicked())); + pb->setMinimumWidth(80); + g->addWidget(pb,2,2); + + pb = new QPushButton(__tr2qs_ctx("Cancel","dcc"),this); + connect(pb,SIGNAL(clicked()),this,SLOT(cancelClicked())); + pb->setMinimumWidth(80); + g->addWidget(pb,2,1); + + g->setColumnStretch(0,1); + g->setRowStretch(1,1); +} + +DccFileTransferBandwidthDialog::~DccFileTransferBandwidthDialog() +{ +} + +void DccFileTransferBandwidthDialog::okClicked() +{ + int iVal = MAX_DCC_BANDWIDTH_LIMIT; + if(m_pEnableLimitCheck->isChecked()) + { + iVal = m_pLimitBox->value(); + if(iVal < 0)iVal = MAX_DCC_BANDWIDTH_LIMIT; + if(iVal > MAX_DCC_BANDWIDTH_LIMIT)iVal = MAX_DCC_BANDWIDTH_LIMIT; + } + m_pTransfer->setBandwidthLimit(iVal); + delete this; +} + +void DccFileTransferBandwidthDialog::cancelClicked() +{ + delete this; +} + +void DccFileTransferBandwidthDialog::closeEvent(QCloseEvent * e) +{ + e->ignore(); + delete this; +} + + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_DccFileTransfer.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/dcc/DccFileTransfer.h b/src/modules/dcc/DccFileTransfer.h new file mode 100644 index 000000000..d55fb3673 --- /dev/null +++ b/src/modules/dcc/DccFileTransfer.h @@ -0,0 +1,256 @@ +#ifndef _SEND_H_ +#define _SEND_H_ +//============================================================================= +// +// File : DccFileTransfer.h +// Creation date : Tue Sep 24 09 2000 15:06:12 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "DccDescriptor.h" +#include "DccWindow.h" +#include "DccThread.h" + +#include "KviWindow.h" +#include "KviCString.h" +#include "kvi_sockettype.h" +#include "KviPointerList.h" +#include "KviFileTransfer.h" +#include "KviTimeUtils.h" +#include "KviTalPopupMenu.h" +#include "KviTalHBox.h" +#include "KviTalVBox.h" + +#include +#include +#include +#include +#include + +class QSpinBox; +class QTimer; +class QPainter; +class DccFileTransfer; +class DccMarshal; +class KviTalPopupMenu; + +typedef struct _KviDccSendThreadOptions +{ + KviCString szFileName; + quint64 uStartPosition; + int iPacketSize; + int iIdleStepLengthInMSec; + bool bFastSend; + bool bNoAcks; + bool bIsTdcc; + unsigned int uMaxBandwidth; +} KviDccSendThreadOptions; + + +class DccSendThread : public DccThread +{ +public: + DccSendThread(QObject * par,kvi_socket_t fd,KviDccSendThreadOptions * opt); + ~DccSendThread(); +private: + // stats: SHARED!!! + uint m_uAverageSpeed; + uint m_uInstantSpeed; + quint64 m_uFilePosition; + quint64 m_uAckedBytes; + quint64 m_uTotalSentBytes; + // internal + unsigned long m_uStartTime; + unsigned long m_uInstantSpeedInterval; + quint64 m_uInstantSentBytes; + KviDccSendThreadOptions * m_pOpt; + KviMSecTimeInterval * m_pTimeInterval; // used for computing the instant bandwidth but not only +public: + void initGetInfo(); + uint averageSpeed(){ return m_uAverageSpeed; }; + uint instantSpeed(){ return m_uInstantSpeed; }; + quint64 filePosition(){ return m_uFilePosition; }; + // sent ONLY in this session + quint64 sentBytes(){ return m_uTotalSentBytes; }; + quint64 ackedBytes(){ return m_uAckedBytes; }; + unsigned int bandwidthLimit(){ return m_pOpt->uMaxBandwidth; }; + void setBandwidthLimit(unsigned int uMaxBandwidth){ m_pOpt->uMaxBandwidth = uMaxBandwidth; }; + void doneGetInfo(); +protected: + void updateStats(); + virtual void run(); +}; + +typedef struct _KviDccRecvThreadOptions +{ + bool bResume; + KviCString szFileName; + quint64 uTotalFileSize; + int iIdleStepLengthInMSec; + bool bSendZeroAck; + bool bNoAcks; + bool bIsTdcc; + unsigned int uMaxBandwidth; +} KviDccRecvThreadOptions; + +class DccRecvThread : public DccThread +{ +public: + DccRecvThread(QObject * par,kvi_socket_t fd,KviDccRecvThreadOptions * opt); + ~DccRecvThread(); +protected: + KviDccRecvThreadOptions * m_pOpt; + + // stats: SHARED! + uint m_uAverageSpeed; + uint m_uInstantSpeed; + quint64 m_uFilePosition; + quint64 m_uTotalReceivedBytes; + + // internal + unsigned long m_uStartTime; + KviMSecTimeInterval * m_pTimeInterval; // used for computing the instant bandwidth + quint64 m_uInstantReceivedBytes; + quint64 m_uInstantSpeedInterval; + QFile * m_pFile; +public: + void initGetInfo(); + uint averageSpeed(){ return m_uAverageSpeed; }; + uint instantSpeed(){ return m_uInstantSpeed; }; + quint64 filePosition(){ return m_uFilePosition; }; + // received ONLY in this session + quint64 receivedBytes(){ return m_uTotalReceivedBytes; }; + unsigned int bandwidthLimit(){ return m_pOpt->uMaxBandwidth; }; + void setBandwidthLimit(unsigned int uMaxBandwidth){ m_pOpt->uMaxBandwidth = uMaxBandwidth; }; + void doneGetInfo(); +protected: + void postMessageEvent(const char * msg); + void updateStats(); + bool sendAck(int filePos); + virtual void run(); +}; + + +class DccFileTransferBandwidthDialog : public QDialog +{ + Q_OBJECT +public: + DccFileTransferBandwidthDialog(QWidget * pParent,DccFileTransfer * t); + ~DccFileTransferBandwidthDialog(); +protected: + DccFileTransfer * m_pTransfer; + QCheckBox * m_pEnableLimitCheck; + QSpinBox * m_pLimitBox; +protected: + virtual void closeEvent(QCloseEvent *e); +protected slots: + void okClicked(); + void cancelClicked(); +}; + + +class DccFileTransfer : public KviFileTransfer, public DccMarshalOutputContext +{ + enum GeneralStatus { Connecting, Transferring, Success, Failure }; + Q_OBJECT +public: + DccFileTransfer(DccDescriptor * dcc); + ~DccFileTransfer(); +private: + DccSendThread * m_pSlaveSendThread; + DccRecvThread * m_pSlaveRecvThread; + DccDescriptor * m_pDescriptor; + DccMarshal * m_pMarshal; + + KviCString m_szTarget; + KviCString m_szDccType; + QString m_szTransferIdString; + + QString m_szStatusString; + GeneralStatus m_eGeneralStatus; + + QString m_szTransferLog; // html + + kvi_time_t m_tTransferStartTime; + kvi_time_t m_tTransferEndTime; + // cached stats + quint64 m_uTotalFileSize; // total file size to transfer + + unsigned int m_uMaxBandwidth; + DccFileTransferBandwidthDialog * m_pBandwidthDialog; + + QTimer * m_pResumeTimer; // used to signal resume timeout +public: + bool resumeAccepted(const char * filename,const char * port,const char *szZeroPortTag); + bool doResume(const char * filename,const char * port,quint64 filePos); + + static void init(); + static void done(); + static unsigned int runningTransfersCount(); + static DccFileTransfer * nonFailedTransferWithLocalFileName(const QString &szLocalFileName); + static unsigned int transferCount(); + static bool handleResumeAccepted(const char * filename,const char * port,const char * szZeroPortTag); + static bool handleResumeRequest(const char * filename,const char * port,quint64 filePos); + + virtual bool event(QEvent *e); + + virtual KviWindow * dccMarshalOutputWindow(); + virtual const char * dccMarshalOutputContextString(); + + virtual void displayPaint(QPainter * p,int column, QRect rect); + virtual int displayHeight(int iLineSpacing); + virtual void fillContextPopup(KviTalPopupMenu * m); + virtual void fillStatusString(QString &szBuffer); + virtual bool active(); + virtual QString tipText(); + virtual QString localFileName(); + + bool isFileUpload(){ return m_pDescriptor->isFileUpload(); }; + + unsigned int averageSpeed(); + unsigned int transferredBytes(); + + int bandwidthLimit(); + void setBandwidthLimit(int iVal); + virtual DccThread * getSlaveThread(); +protected: + void startConnection(); + void listenOrConnect(); + void addToTransferLog(const QString &s); + void outputAndLog(const QString &s); + void outputAndLog(int msgtype,const QString &s); + KviWindow * eventWindow(); +protected slots: + void connectionInProgress(); + void sslError(const char * msg); + void startingSSLHandshake(); + void handleMarshalError(KviError::Code); + void connected(); + void bandwidthDialogDestroyed(); + void configureBandwidth(); + void resumeTimedOut(); +public slots: + void abort(); + void retryDCC(); + void retryTDCC(); + void retryRevDCC(); +}; + +#endif //_SEND_H_ diff --git a/src/modules/dcc/DccMarshal.cpp b/src/modules/dcc/DccMarshal.cpp new file mode 100644 index 000000000..719ca33a8 --- /dev/null +++ b/src/modules/dcc/DccMarshal.cpp @@ -0,0 +1,657 @@ +//============================================================================= +// +// File : DccMarshal.cpp +// Creation date : Sun Sep 17 2000 15:59:11 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "DccMarshal.h" + +#include "kvi_settings.h" +#include "KviNetUtils.h" +#include "KviOptions.h" +#include "KviLocale.h" +#include "KviMemory.h" +#include "kvi_socket.h" +#include "KviFileUtils.h" + +#include //for exit() + +#include + +DccMarshal::DccMarshal(DccMarshalOutputContext * ctx) +: QObject(0) +{ + setObjectName("dcc_marshal"); + m_pSn = 0; + m_fd = KVI_INVALID_SOCKET; + m_pTimeoutTimer = 0; + m_bIPv6 = false; + m_pOutputContext = ctx; +#ifdef COMPILE_SSL_SUPPORT + m_pSSL = 0; +#endif + m_szIp = ""; + m_szPort = ""; + m_szSecondaryIp = ""; + m_szSecondaryPort = ""; +} + +DccMarshal::~DccMarshal() +{ + reset(); +} + +kvi_socket_t DccMarshal::releaseSocket() +{ + kvi_socket_t aux_fd = m_fd; + m_fd = KVI_INVALID_SOCKET; + return aux_fd; +} + +#ifdef COMPILE_SSL_SUPPORT +KviSSL * DccMarshal::releaseSSL() +{ + KviSSL * theSSL = m_pSSL; + m_pSSL = 0; + return theSSL; +} +#endif + +void DccMarshal::reset() +{ + if(m_pSn) + { + delete m_pSn; + m_pSn = 0; + } + if(m_fd != KVI_INVALID_SOCKET) + { + kvi_socket_close(m_fd); + m_fd = KVI_INVALID_SOCKET; + } +#ifdef COMPILE_SSL_SUPPORT +// qDebug("MARSHAL RESETTING (SSL=%d)",m_pSSL); + if(m_pSSL) + { +// qDebug("MARSHAL CLEARING THE SSL"); + KviSSLMaster::freeSSL(m_pSSL); + m_pSSL = 0; + } +#endif + if(m_pTimeoutTimer) + { + delete m_pTimeoutTimer; + m_pTimeoutTimer = 0; + } + m_bIPv6 = false; +} + +KviError::Code DccMarshal::dccListen(const QString &ip,const QString &port,bool bUseTimeout,bool bUseSSL) +{ + if(m_fd != KVI_INVALID_SOCKET) + return KviError::AnotherConnectionInProgress; + + m_szIp = ip; + m_szPort = port; + + m_bOutgoing = false; + + m_bUseTimeout = bUseTimeout; + + if(m_pTimeoutTimer) + { + delete m_pTimeoutTimer; + m_pTimeoutTimer = 0; + } + +#ifdef COMPILE_SSL_SUPPORT + m_bUseSSL = bUseSSL; +#else + if(bUseSSL) + return KviError::NoSSLSupport; +#endif + QTimer::singleShot(100, this, SLOT(doListen())); + + return KviError::Success; +} + +void DccMarshal::doListen() +{ + // Check the address type + if(!KviNetUtils::isValidStringIp(m_szIp)) + { +#ifdef COMPILE_IPV6_SUPPORT + if(!KviNetUtils::isValidStringIPv6(m_szIp)) + { + emit error(KviError::InvalidIpAddress); + return; + } else m_bIPv6 = true; +#else + emit error(KviError::InvalidIpAddress); + return; +#endif + } + + bool bOk; + m_uPort = m_szPort.toUInt(&bOk); + if(!bOk) + { + emit error(KviError::InvalidPortNumber); + return; + } + +#ifndef COMPILE_IPV6_SUPPORT + if(m_bIPv6) + { + emit error(KviError::NoIPv6Support); + return; + } +#endif + + +#ifdef COMPILE_IPV6_SUPPORT + m_fd = kvi_socket_create(m_bIPv6 ? KVI_SOCKET_PF_INET6 : KVI_SOCKET_PF_INET, + KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); +#else + m_fd = kvi_socket_create(KVI_SOCKET_PF_INET,KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); +#endif + + if(m_fd == KVI_INVALID_SOCKET) + { + emit error(KviError::SocketCreationFailed); + return; + } + + if((!KVI_OPTION_BOOL(KviOption_boolUserDefinedPortRange)) || (m_uPort != 0)) + { +#ifdef COMPILE_IPV6_SUPPORT + KviSockaddr sa(m_szIp.toUtf8().data(),m_uPort,m_bIPv6); +#else + KviSockaddr sa(m_szIp.toUtf8().data(),m_uPort,false); +#endif + + if(!sa.socketAddress()) + { + reset(); + emit error(KviError::BindFailed); + return; + } + + if(!kvi_socket_bind(m_fd,sa.socketAddress(),sa.addressLength())) + { + reset(); + emit error(KviError::BindFailed); + return; + } + + } else { + m_uPort = KVI_OPTION_UINT(KviOption_uintDccMinPort); + if(KVI_OPTION_UINT(KviOption_uintDccMaxPort) > 65535)KVI_OPTION_UINT(KviOption_uintDccMaxPort) = 65535; + bool bBindSuccess; + do { +#ifdef COMPILE_IPV6_SUPPORT + KviSockaddr sa(m_szIp.toUtf8().data(),m_uPort,m_bIPv6); +#else + KviSockaddr sa(m_szIp.toUtf8().data(),m_uPort,false); +#endif + if(!sa.socketAddress()) + { + reset(); + emit error(KviError::BindFailed); + return; + } + + bBindSuccess = kvi_socket_bind(m_fd,sa.socketAddress(),sa.addressLength()); + + if(!bBindSuccess) + { + if(m_uPort == 65535) + { + reset(); + emit error(KviError::BindFailed); + return; + } + m_uPort++; + } + + } while((!bBindSuccess) && (m_uPort <= KVI_OPTION_UINT(KviOption_uintDccMaxPort))); + + if(!bBindSuccess) + { + reset(); + emit error(KviError::BindFailed); + return; + } + + } + + if(!kvi_socket_listen(m_fd,1)) + { + reset(); + emit error(KviError::ListenFailed); + return; + } + + + // Reread the port in case we're binding to a random one (0) + +#ifdef COMPILE_IPV6_SUPPORT + KviSockaddr sareal(0,m_bIPv6); +#else + KviSockaddr sareal(0,false); +#endif + + + int size = sareal.addressLength(); + + if(kvi_socket_getsockname(m_fd,sareal.socketAddress(),&size)) + { +// qDebug("GETSOCKNAMEOK"); + m_szPort.setNum(sareal.port()); + m_uPort = sareal.port(); +// qDebug("REALPORT %u",m_uPort); + } else { +// qDebug("GETSOCKNAMEFAILED"); + } + + // and setup the READ notifier... + m_pSn = new QSocketNotifier(m_fd,QSocketNotifier::Read); + QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(snActivated(int))); + m_pSn->setEnabled(true); + + // set the timer + if(KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) < 5) + KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) = 5; + + if(m_pTimeoutTimer) + { + delete m_pTimeoutTimer; + m_pTimeoutTimer = 0; + } + + if(m_bUseTimeout) + { + m_pTimeoutTimer = new QTimer(); + connect(m_pTimeoutTimer,SIGNAL(timeout()),this,SLOT(connectionTimedOut())); + m_pTimeoutTimer->setSingleShot(true); + m_pTimeoutTimer->setInterval((KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) * 1000)); + m_pTimeoutTimer->start(); + } + // and wait for connect + + emit inProgress(); +} + +KviError::Code DccMarshal::dccConnect(const char * ip,const char * port,bool bUseTimeout,bool bUseSSL) +{ + if(m_fd != KVI_INVALID_SOCKET) + return KviError::AnotherConnectionInProgress; + + m_bUseTimeout = bUseTimeout; + m_szIp = ip; + m_szPort = port; + m_bOutgoing = true; + +#ifdef COMPILE_SSL_SUPPORT + m_bUseSSL = bUseSSL; +#else + if(bUseSSL) + return KviError::NoSSLSupport; +#endif + + QTimer::singleShot(100, this, SLOT(doConnect())); + return KviError::Success; +} + +void DccMarshal::doConnect() +{ + if(m_pTimeoutTimer) + { + delete m_pTimeoutTimer; + m_pTimeoutTimer = 0; + } + // Check the address type + if(!KviNetUtils::isValidStringIp(m_szIp)) + { +#ifdef COMPILE_IPV6_SUPPORT + if(!KviNetUtils::isValidStringIPv6(m_szIp)) + { + emit error(KviError::InvalidIpAddress); + return; + } else m_bIPv6 = true; +#else + emit error(KviError::InvalidIpAddress); + return; +#endif + } + + bool bOk; + m_uPort = m_szPort.toUInt(&bOk); + if(!bOk) + { + emit error(KviError::InvalidPortNumber); + return; + } + + + // create the socket +#ifdef COMPILE_IPV6_SUPPORT + m_fd = kvi_socket_create(m_bIPv6 ? KVI_SOCKET_PF_INET6 : KVI_SOCKET_PF_INET, + KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); +#else + m_fd = kvi_socket_create(KVI_SOCKET_PF_INET, + KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); +#endif + if(m_fd == KVI_INVALID_SOCKET) + { + emit error(KviError::SocketCreationFailed); + return; + } + + // make it non blocking + if(!kvi_socket_setNonBlocking(m_fd)) + { + reset(); + emit error(KviError::AsyncSocketFailed); + return; + } + + + // fill the sockaddr structure + +#ifdef COMPILE_IPV6_SUPPORT + KviSockaddr sa(m_szIp.toUtf8().data(),m_uPort,m_bIPv6); +#else + KviSockaddr sa(m_szIp.toUtf8().data(),m_uPort,false); +#endif + + if(!sa.socketAddress()) + { + reset(); + emit error(KviError::SocketCreationFailed); + return; + } + + if(!kvi_socket_connect(m_fd,sa.socketAddress(),sa.addressLength())) + { + int err = kvi_socket_error(); + + if(!kvi_socket_recoverableConnectError(err)) + { + // Ops... + int sockError=err; + if(sockError==0) + { + // Zero error ?...let's look closer + int iSize=sizeof(int); + if(!kvi_socket_getsockopt(m_fd,SOL_SOCKET,SO_ERROR, + (void *)&sockError,&iSize))sockError=0; + } + // Die + reset(); + // And declare problems :) + if(sockError)emit error(KviError::translateSystemError(sockError)); + else emit error(KviError::UnknownError); //Error 0 ? + return; + } + } + + + // and setup the WRITE notifier... + m_pSn = new QSocketNotifier(m_fd,QSocketNotifier::Write); + QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(snActivated(int))); + m_pSn->setEnabled(true); + + // set the timer + if(KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) < 5) + KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) = 5; + + if(m_pTimeoutTimer) + { + delete m_pTimeoutTimer; + m_pTimeoutTimer = 0; + } + + if(m_bUseTimeout) + { + m_pTimeoutTimer = new QTimer(); + connect(m_pTimeoutTimer,SIGNAL(timeout()),this,SLOT(connectionTimedOut())); + m_pTimeoutTimer->setSingleShot(true); + m_pTimeoutTimer->setInterval(KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) * 1000); + m_pTimeoutTimer->start(); + } + + // and wait for connect + emit inProgress(); +} + + +void DccMarshal::snActivated(int) +{ + if(m_pTimeoutTimer) + { + delete m_pTimeoutTimer; + m_pTimeoutTimer = 0; + } +#ifdef COMPILE_IPV6_SUPPORT + struct sockaddr_in6 hostSockAddr6; +#endif + struct sockaddr_in hostSockAddr; + + int size = sizeof(hostSockAddr); + struct sockaddr * addr = (struct sockaddr *)&hostSockAddr; + +#ifdef COMPILE_IPV6_SUPPORT + if(m_bIPv6) + { + addr = (struct sockaddr *)&hostSockAddr6; + size = sizeof(hostSockAddr6); + } +#endif + + if(m_bOutgoing) + { + // outgoing connection (we have called connect()) + // Check for errors... + int sockError; + int iSize=sizeof(int); + if(!kvi_socket_getsockopt(m_fd,SOL_SOCKET,SO_ERROR,(void *)&sockError,&iSize))sockError = -1; + if(sockError != 0) + { + //failed + if(sockError > 0)sockError = KviError::translateSystemError(sockError); + else sockError = KviError::UnknownError; //Error 0 ? + reset(); + emit error(sockError); + return; + } + //Succesfully connected... + delete m_pSn; + m_pSn = 0; + // get the local address + if(!kvi_socket_getsockname(m_fd,addr,&size)) + { + m_szSecondaryIp = "localhost"; + m_szSecondaryPort = __tr2qs_ctx("unknown","dcc"); + } else { +#ifdef COMPILE_IPV6_SUPPORT + if(m_bIPv6) + { + m_szSecondaryPort.setNum(ntohs(((struct sockaddr_in6 *)addr)->sin6_port)); + if(!KviNetUtils::binaryIpToStringIp_V6(((struct sockaddr_in6 *)addr)->sin6_addr,m_szSecondaryIp)) + m_szSecondaryIp = "localhost"; + } else { +#endif + m_szSecondaryPort.setNum(ntohs(((struct sockaddr_in *)addr)->sin_port)); + if(!KviNetUtils::binaryIpToStringIp(((struct sockaddr_in *)addr)->sin_addr,m_szSecondaryIp)) + m_szSecondaryIp = "localhost"; +#ifdef COMPILE_IPV6_SUPPORT + } +#endif + } + } else { + // Incoming connection + int newsock = kvi_socket_accept(m_fd,addr,&size); + if(newsock != KVI_INVALID_SOCKET) + { + // Connected + delete m_pSn; + m_pSn = 0; +#ifdef COMPILE_IPV6_SUPPORT + if(m_bIPv6) + { + m_szSecondaryPort.setNum(ntohs(((struct sockaddr_in6 *)addr)->sin6_port)); + if(!KviNetUtils::binaryIpToStringIp_V6(((struct sockaddr_in6 *)addr)->sin6_addr,m_szSecondaryIp)) + m_szSecondaryIp = __tr2qs_ctx("unknown","dcc"); + } else { +#endif + m_szSecondaryPort.setNum(ntohs(((struct sockaddr_in *)addr)->sin_port)); + if(!KviNetUtils::binaryIpToStringIp(((struct sockaddr_in *)addr)->sin_addr,m_szSecondaryIp)) + m_szSecondaryIp = __tr2qs_ctx("unknown","dcc"); +#ifdef COMPILE_IPV6_SUPPORT + } +#endif + kvi_socket_close(m_fd); + m_fd = newsock; + if(!kvi_socket_setNonBlocking(m_fd)) + { + reset(); + emit error(KviError::AsyncSocketFailed); + return; + } + + } else { + // Huh ?.. wait for the next notifier call + return; + } + } + +#ifdef COMPILE_SSL_SUPPORT + // SSL Handshake needed ? + if(m_bUseSSL) + { + m_pSSL = KviSSLMaster::allocSSL(m_pOutputContext->dccMarshalOutputWindow(),m_fd,m_bOutgoing ? KviSSL::Client : KviSSL::Server,m_pOutputContext->dccMarshalOutputContextString()); + + if(m_pSSL) + { + emit startingSSLHandshake(); + doSSLHandshake(0); + } else { + reset(); + emit error(KviError::SSLError); + } + return; + } +#endif + + emit connected(); +} + +void DccMarshal::doSSLHandshake(int) +{ +#ifdef COMPILE_SSL_SUPPORT +// qDebug("DO SSL HANDSHAKE"); + if(m_pSn) + { + delete m_pSn; + m_pSn = 0; + } + + if(!m_pSSL) + { + qDebug("Ops... I've lost the SSL class ?"); + reset(); + emit error(KviError::InternalError); + return; // ops ? + } + + KviSSL::Result r = m_bOutgoing ? m_pSSL->connect() : m_pSSL->accept(); + + switch(r) + { + case KviSSL::Success: + // done! +// qDebug("EMITTING CONNECTED"); + emit connected(); +// qDebug("CONNECTED EMITTED"); + break; + case KviSSL::WantRead: + m_pSn = new QSocketNotifier((int)m_fd,QSocketNotifier::Read); + QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(doSSLHandshake(int))); + m_pSn->setEnabled(true); + break; + case KviSSL::WantWrite: + m_pSn = new QSocketNotifier((int)m_fd,QSocketNotifier::Write); + QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(doSSLHandshake(int))); + m_pSn->setEnabled(true); + break; + case KviSSL::RemoteEndClosedConnection: + reset(); + emit error(KviError::RemoteEndClosedConnection); + break; + case KviSSL::SyscallError: + { + // syscall problem + int err = kvi_socket_error(); + if(kvi_socket_recoverableError(err)) + { + // can recover ? (EAGAIN, EINTR ?) + m_pSn = new QSocketNotifier((int)m_fd,QSocketNotifier::Write); + QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(doSSLHandshake(int))); + m_pSn->setEnabled(true); + return; + } else { + // Declare problems :) + reset(); + emit error(err ? KviError::translateSystemError(err) : KviError::UnknownError); + } + } + break; + default: + { + KviCString buffer; + while(m_pSSL->getLastErrorString(buffer))emit sslError(buffer.ptr()); + reset(); + emit error(KviError::SSLError); + } + break; + } +#else //!COMPILE_SSL_SUPPORT + qDebug("Ops.. ssl handshake without ssl support!...aborting!"); + exit(-1); +#endif //!COMPILE_SSL_SUPPORT +} + +void DccMarshal::abort() +{ + reset(); +} + +void DccMarshal::connectionTimedOut() +{ + reset(); + emit error(KviError::ConnectionTimedOut); +} + + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_DccMarshal.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/dcc/DccMarshal.h b/src/modules/dcc/DccMarshal.h new file mode 100644 index 000000000..228905224 --- /dev/null +++ b/src/modules/dcc/DccMarshal.h @@ -0,0 +1,116 @@ +#ifndef _MARSHAL_H_ +#define _MARSHAL_H_ +//============================================================================= +// +// File DccMarshal.h +// Creation date : Sun Sep 17 2000 10:44:20 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviCString.h" +#include "KviError.h" +#include "kvi_sockettype.h" +#include "kvi_inttypes.h" + +#include +#include +#include + +class KviWindow; +class DccMarshal; + +#ifdef COMPILE_SSL_SUPPORT + #include "KviSSLMaster.h" +#endif + + +class DccMarshalOutputContext +{ + friend class DccMarshal; +public: + DccMarshalOutputContext(){}; + virtual ~DccMarshalOutputContext(){}; +protected: + virtual KviWindow * dccMarshalOutputWindow() = 0; + virtual const char * dccMarshalOutputContextString() = 0; +}; + +class DccMarshal : public QObject +{ + Q_OBJECT +public: + DccMarshal(DccMarshalOutputContext * ctx); + ~DccMarshal(); +protected: + // DCC DESCRIPTOR + QString m_szIp; // Dcc initiator ip address (the one that listens) + QString m_szPort; // Dcc initiator port (the one that listens) + // other info + bool m_bIPv6; // Dcc mode + kvi_u32_t m_uPort; // Dcc initiator port + bool m_bOutgoing; // true if WE have connected to the remote host (so m_szIp is the remote host ip) + QString m_szSecondaryIp; // Ip of the client that has connected to the remote host + QString m_szSecondaryPort; // Port of the client that has connected to the remote host + // internals + kvi_socket_t m_fd; // socket + QSocketNotifier * m_pSn; + bool m_bUseTimeout; + QTimer * m_pTimeoutTimer; +#ifdef COMPILE_SSL_SUPPORT + KviSSL * m_pSSL; + bool m_bUseSSL; +#endif + DccMarshalOutputContext * m_pOutputContext; +public: + const QString & dccIp() const { return m_szIp; }; + const QString & dccPort() const { return m_szPort; }; + const QString & localIp() const { return m_bOutgoing ? m_szSecondaryIp : m_szIp; }; + const QString & localPort() const { return m_bOutgoing ? m_szSecondaryPort : m_szPort; }; + const QString & remoteIp() const { return m_bOutgoing ? m_szIp : m_szSecondaryIp; }; + const QString & remotePort() const { return m_bOutgoing ? m_szPort : m_szSecondaryPort; }; + KviError::Code dccListen(const QString &ip,const QString &port,bool bUseTimeout,bool bUseSSL = false); + KviError::Code dccConnect(const char * ip,const char * port,bool bUseTimeout,bool bUseSSL = false); + kvi_socket_t releaseSocket(); +#ifdef COMPILE_SSL_SUPPORT + KviSSL * releaseSSL(); +#endif + void abort(); +private: + void reset(); +//#ifdef COMPILE_SSL_SUPPORT +// bool trySSLCertificate(); +//#endif +private slots: + void doSSLHandshake(int); +// void doListenSSLHandshake(); + void snActivated(int); + void connectionTimedOut(); + void doListen(); + void doConnect(); +signals: + void startingSSLHandshake(); + void sslError(const char * msg); + void connected(); + void inProgress(); + void error(int); +}; + + +#endif //_MARSHAL_H_ diff --git a/src/modules/dcc/DccThread.cpp b/src/modules/dcc/DccThread.cpp new file mode 100644 index 000000000..adc8dc1c2 --- /dev/null +++ b/src/modules/dcc/DccThread.cpp @@ -0,0 +1,114 @@ +//============================================================================= +// +// File : DccThread.cpp +// Creation date : Tue Sep 20 09 2000 18:29:51 CEST Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "DccThread.h" + +#include "kvi_debug.h" +#include "KviWindow.h" +#include "KviError.h" +#include "KviMemory.h" +#include "KviMemory.h" +#include "KviNetUtils.h" +#include "kvi_socket.h" + +#ifdef COMPILE_SSL_SUPPORT + #include "KviSSLMaster.h" +#endif + +DccThread::DccThread(QObject * par,kvi_socket_t fd) +: KviSensitiveThread() +{ + m_pParent = par; + m_fd = fd; + m_pMutex = new KviMutex(); +#ifdef COMPILE_SSL_SUPPORT +// qDebug("CLEARING SSL IN DccThread constructor"); + m_pSSL = 0; +#endif +} + +DccThread::~DccThread() +{ +#ifdef COMPILE_SSL_SUPPORT + if(m_pSSL)KviSSLMaster::freeSSL(m_pSSL); + m_pSSL = 0; +#endif + if(m_fd != KVI_INVALID_SOCKET)kvi_socket_close(m_fd); + KVI_ASSERT(!m_pMutex->locked()); + delete m_pMutex; +} + +#ifdef COMPILE_SSL_SUPPORT +void DccThread::setSSL(KviSSL * s) +{ + if(m_pSSL)KviSSLMaster::freeSSL(m_pSSL); + m_pSSL = s; +} +#endif + +bool DccThread::handleInvalidSocketRead(int readLen) +{ + KVI_ASSERT(readLen < 1); + if(readLen == 0) + { + // connection closed + postErrorEvent(KviError::RemoteEndClosedConnection); + return false; + } else { + // error ? + int err = kvi_socket_error(); + if((err != EINTR) && (err != EAGAIN)) + { + postErrorEvent(KviError::translateSystemError(err)); + return false; + } + } + return true; // continue +} + +#ifdef COMPILE_SSL_SUPPORT +void DccThread::raiseSSLError() +{ + KviCString buffer; + while(m_pSSL->getLastErrorString(buffer)) + { + KviCString msg(KviCString::Format,"[SSL ERROR]: %s",buffer.ptr()); + postMessageEvent(msg.ptr()); + } +} +#endif + +void DccThread::postErrorEvent(int err) +{ + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ERROR); + e->setData(new int(err)); + postEvent(m_pParent,e); +} + +void DccThread::postMessageEvent(const char * message) +{ + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_MESSAGE); + e->setData(new KviCString(message)); + postEvent(m_pParent,e); +} diff --git a/src/modules/dcc/DccThread.h b/src/modules/dcc/DccThread.h new file mode 100644 index 000000000..0fc8f366b --- /dev/null +++ b/src/modules/dcc/DccThread.h @@ -0,0 +1,81 @@ +#ifndef _THREAD_H_ +#define _THREAD_H_ +//============================================================================= +// +// File : DccThread.h +// Creation date : Tue Sep 20 09 2000 18:28:44 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" +#include "KviThread.h" +#include "kvi_sockettype.h" +#include "KviPointerList.h" + +#include + +#ifdef COMPILE_SSL_SUPPORT + #include "KviSSL.h" +#endif + +// KviThreadDataEvent +#define KVI_DCC_THREAD_EVENT_ERROR (KVI_THREAD_USER_EVENT_BASE + 1) +// KviThreadDataEvent +#define KVI_DCC_THREAD_EVENT_DATA (KVI_THREAD_USER_EVENT_BASE + 2) +// KviThreadEvent +#define KVI_DCC_THREAD_EVENT_SUCCESS (KVI_THREAD_USER_EVENT_BASE + 3) +// KviThreadDataEvent +#define KVI_DCC_THREAD_EVENT_MESSAGE (KVI_THREAD_USER_EVENT_BASE + 4) +// KviThreadDataEvent +#define KVI_DCC_THREAD_EVENT_ACTION (KVI_THREAD_USER_EVENT_BASE + 5) + +typedef struct _KviDccThreadIncomingData +{ + int iLen; + char * buffer; +} KviDccThreadIncomingData; + +class DccThread : public KviSensitiveThread +{ +public: + DccThread(QObject * par,kvi_socket_t fd); + ~DccThread(); +protected: + KviMutex * m_pMutex; // OWNED! PROTECTS m_pOutBuffers + kvi_socket_t m_fd; + QObject * m_pParent; // READ ONLY! +#ifdef COMPILE_SSL_SUPPORT + KviSSL * m_pSSL; +#endif +protected: + bool handleInvalidSocketRead(int readLen); +public: + QObject * parent(){ return m_pParent; }; + void postErrorEvent(int err); + // Warning!..newer call __tr() here!...use __tr_no_lookup() + void postMessageEvent(const char * message); +#ifdef COMPILE_SSL_SUPPORT + void raiseSSLError(); + void setSSL(KviSSL * s); + KviSSL * getSSL() const { return m_pSSL; }; +#endif +}; + +#endif //_THREAD_H_ diff --git a/src/modules/dcc/DccUtils.cpp b/src/modules/dcc/DccUtils.cpp new file mode 100644 index 000000000..6d794a9de --- /dev/null +++ b/src/modules/dcc/DccUtils.cpp @@ -0,0 +1,170 @@ +//============================================================================= +// +// File : DccUtils.cpp +// Creation date : Tue Jul 23 02:54:44 2002 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#define _UTILS_CPP_ + +#include "DccUtils.h" + +#include "KviOptions.h" +#include "KviLocale.h" +#include "KviNetUtils.h" +#include "KviIrcSocket.h" +#include "KviIrcLink.h" +#include "KviQString.h" + +/* +bool dcc_module_get_listen_ip_address(KviCommand *c,KviConsoleWindow * pConsole,QString &szListenIp) +{ + // + // Find an interface suitable for listening.... + // Either from user options or from the current connection... + // + + if(KVI_OPTION_BOOL(KviOption_boolDccListenOnSpecifiedInterfaceByDefault)) + { + KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).trimmed(); + if(!KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).isEmpty()) + { + if(kvi_isValidStringIp(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).toUtf8().data())) + { + if(KviQString::equalCI(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface),"0.0.0.0")) + { + // Try to find the first available IPv4 interface + if(!kvi_getLocalHostAddress(szListenIp)) + { + if(c)c->warning(__tr2qs_ctx("Can't retrieve a suitable local IPV4 address","dcc"), + KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).toUtf8().data()); + return false; + } + } else { + szListenIp = KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface); + } + return true; + } +#ifdef COMPILE_IPV6_SUPPORT + if(kvi_isValidStringIPv6(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).toUtf8().data())) + { + szListenIp = KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface); + } else { +#endif + if(!kvi_getInterfaceAddress(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).toUtf8().data(),szListenIp)) + { + KVI_OPTION_BOOL(KviOption_boolDccListenOnSpecifiedInterfaceByDefault) = false; + if(c)c->warning(__tr2qs_ctx("Can't listen on default interface '%s': fix it in the options dialog, disabling the option (so the next dcc will work)","dcc"), + KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).toUtf8().data()); + return false; + } +#ifdef COMPILE_IPV6_SUPPORT + } +#endif + return true; + } else { + // the option was empty.. disable it + KVI_OPTION_BOOL(KviOption_boolDccListenOnSpecifiedInterfaceByDefault) = false; + } + } + + if(pConsole) + { + if(pConsole->isConnected()) + { + //#warning "The IPV6 choice is not OK here.... and maybe allow to bind to specified ports" + pConsole->socket()->getLocalHostIp(szListenIp,pConsole->isIPv6Connection()); + } else { + szListenIp = "0.0.0.0"; // huh ? :) + } + } else { + szListenIp = "0.0.0.0"; + } + + return true; +} +*/ + +bool dcc_kvs_get_listen_ip_address(KviKvsModuleCommandCall *c,KviConsoleWindow * pConsole,QString &szListenIp) +{ + // + // Find an interface suitable for listening.... + // Either from user options or from the current connection... + // + + if(KVI_OPTION_BOOL(KviOption_boolDccListenOnSpecifiedInterfaceByDefault)) + { + KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).trimmed(); + if(!KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).isEmpty()) + { + if(KviNetUtils::isValidStringIp(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).toUtf8().data())) + { + if(KviQString::equalCI(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface),"0.0.0.0")) + { + // Try to find the first available IPv4 interface + if(!kvi_getLocalHostAddress(szListenIp)) + { + if(c)c->warning(__tr2qs_ctx("Can't retrieve a suitable local IPV4 address","dcc"), + KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).toUtf8().data()); + return false; + } + } else { + szListenIp = KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface); + } + return true; + } +#ifdef COMPILE_IPV6_SUPPORT + if(KviNetUtils::isValidStringIPv6(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).toUtf8().data())) + { + szListenIp = KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface); + } else { +#endif + if(!KviNetUtils::getInterfaceAddress(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface),szListenIp)) + { + KVI_OPTION_BOOL(KviOption_boolDccListenOnSpecifiedInterfaceByDefault) = false; + if(c)c->warning(__tr2qs_ctx("Can't listen on default interface '%s': fix it in the options dialog, disabling the option (so the next dcc will work)","dcc"), + KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).toUtf8().data()); + return false; + } +#ifdef COMPILE_IPV6_SUPPORT + } +#endif + return true; + } else { + // the option was empty.. disable it + KVI_OPTION_BOOL(KviOption_boolDccListenOnSpecifiedInterfaceByDefault) = false; + } + } + + if(pConsole) + { + if(pConsole->isConnected()) + { + //#warning "The IPV6 choice is not OK here.... and maybe allow to bind to specified ports" + pConsole->connection()->link()->socket()->getLocalHostIp(szListenIp,pConsole->isIPv6Connection()); + } else { + szListenIp = "0.0.0.0"; // huh ? :) + } + } else { + szListenIp = "0.0.0.0"; + } + + return true; +} diff --git a/src/modules/dcc/DccUtils.h b/src/modules/dcc/DccUtils.h new file mode 100644 index 000000000..1937adb15 --- /dev/null +++ b/src/modules/dcc/DccUtils.h @@ -0,0 +1,36 @@ +#ifndef _UTILS_H_ +#define _UTILS_H_ +//============================================================================= +// +// File : DccUtils.h +// Creation date : Tue Jul 23 02:54:45 2002 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" +#include "KviCString.h" +#include "KviConsoleWindow.h" +#include "KviKvsModuleInterface.h" + +#ifndef _UTILS_CPP_ + extern bool dcc_kvs_get_listen_ip_address(KviKvsModuleCommandCall *c,KviConsoleWindow * pConsole,QString &szListenIp); +#endif + +#endif //_UTILS_H_ diff --git a/src/modules/dcc/DccVideoWindow.cpp b/src/modules/dcc/DccVideoWindow.cpp new file mode 100644 index 000000000..f9464158f --- /dev/null +++ b/src/modules/dcc/DccVideoWindow.cpp @@ -0,0 +1,1032 @@ +//============================================================================= +// +// File : DccVideoWindow.cpp +// Creation date : Tue Nov 10 18:08:09 2009 GMT by Fabio Bas +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2009 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" + +#include "DccVideoWindow.h" +#include "DccMarshal.h" +#include "DccBroker.h" + +#include "KviIconManager.h" +#include "KviIrcView.h" +#include "KviKvsEventTriggers.h" +#include "KviLocale.h" +#include "kvi_out.h" +#include "KviNetUtils.h" +#include "KviOptions.h" +#include "KviConsoleWindow.h" +#include "KviMemory.h" +#include "kvi_socket.h" +#include "KviIrcConnection.h" +#include "KviTalVBox.h" +#include "KviMircCntrl.h" +#include "KviMainWindow.h" + +#include +#include +#include +#include //for Qt::escape + +#ifdef COMPILE_CRYPT_SUPPORT + #include "KviCryptController.h" +#endif + +#ifdef COMPILE_SSL_SUPPORT + #include "KviSSLMaster.h" +#endif + +#include + +#define FRAME_DURATION 200 // 1 / 5fps = 200msec + +extern DccBroker * g_pDccBroker; + +#ifndef COMPILE_DISABLE_DCC_VIDEO + Kopete::AV::VideoDevicePool *g_pVideoDevicePool=0; + int g_iVideoDevicePoolInstances=0; +#endif + +bool kvi_dcc_video_is_valid_codec(const char * codecName) +{ + if(kvi_strEqualCI("sjpeg",codecName))return true; +#ifndef COMPILE_DISABLE_OGG_THEORA + if(kvi_strEqualCI("theora",codecName))return true; +#endif + return false; +} + +static DccVideoCodec * kvi_dcc_video_get_codec(const char *codecName) +{ +#ifndef COMPILE_DISABLE_OGG_THEORA + if(kvi_strEqualCI("theora",codecName))return new DccVideoTheoraCodec(); +#endif + return new DccVideoSJpegCodec(); +} + + +DccVideoThread::DccVideoThread(KviWindow * wnd,kvi_socket_t fd,KviDccVideoThreadOptions * opt) +: DccThread(wnd,fd) +{ +#ifndef COMPILE_DISABLE_DCC_VIDEO + m_pOpt = opt; + m_bPlaying = false; + m_bRecording = false; + + //local video input + if(!g_pVideoDevicePool) + { + g_pVideoDevicePool = Kopete::AV::VideoDevicePool::self(); + g_pVideoDevicePool->open(); + g_pVideoDevicePool->setSize(320, 240); + } + g_iVideoDevicePoolInstances++; + //ensure capturing + g_pVideoDevicePool->startCapturing(); +#endif + startRecording(); + startPlaying(); + +} + +DccVideoThread::~DccVideoThread() +{ + stopRecording(); +#ifndef COMPILE_DISABLE_DCC_VIDEO + g_iVideoDevicePoolInstances--; + if(g_iVideoDevicePoolInstances==0) + g_pVideoDevicePool->close(); + + delete m_pOpt->pCodec; + delete m_pOpt; +#endif +} + +bool DccVideoThread::readWriteStep() +{ +// qDebug("DccVideoThread::readWriteStep()"); +#ifndef COMPILE_DISABLE_DCC_VIDEO + // Socket management + bool bCanRead; + bool bCanWrite; + + if(kvi_select(m_fd,&bCanRead,&bCanWrite)) + { + while(bCanRead) + { + unsigned int actualSize = m_inFrameBuffer.size(); + m_inFrameBuffer.resize(actualSize + 16384); + int readLen = kvi_socket_recv(m_fd,(void *)(m_inFrameBuffer.data() + actualSize),16384); + if(readLen > 0) + { + if(readLen < 16384)m_inFrameBuffer.resize(actualSize + readLen); + m_pOpt->pCodec->decode(&m_inFrameBuffer,&m_videoInSignalBuffer,&m_textInSignalBuffer); + } else { + bCanRead=false; +// if(!handleInvalidSocketRead(readLen))return false; + m_inFrameBuffer.resize(actualSize); + } + } + + if(bCanWrite) + { + // Have somethihg to write ? + if(m_outFrameBuffer.size() > 0) + { + int written = kvi_socket_send(m_fd,m_outFrameBuffer.data(),m_outFrameBuffer.size()); + if(written > 0) + { + m_outFrameBuffer.remove(written); + } else { + if(!handleInvalidSocketRead(written))return false; + } + } + } + } +#endif // !COMPILE_DISABLE_DCC_VOICE + return true; +} + +bool DccVideoThread::videoStep() +{ +// qDebug("DccVideoThread::videoStep()"); +#ifndef COMPILE_DISABLE_DCC_VIDEO + // Are we playing ? + if(m_bPlaying) + { + if(m_videoInSignalBuffer.size() > 0) + { + QImage img(m_videoInSignalBuffer.data(), 320, 240, 1280, QImage::Format_ARGB32); +// qDebug("IMG data %p size %d", m_videoInSignalBuffer.data(), m_videoInSignalBuffer.size()); + if(!img.isNull()) + m_inImage = img; + } + } + + // Are we recording ? + if(m_bRecording) + { + //grab the image, compress using the codec + g_pVideoDevicePool->getFrame(); + g_pVideoDevicePool->getImage(&m_outImage); + if(m_outImage.numBytes() > 0) + { + m_videoOutSignalBuffer.append((const unsigned char*) m_outImage.bits(), m_outImage.numBytes()); + m_pOpt->pCodec->encodeVideo(&m_videoOutSignalBuffer,&m_outFrameBuffer); + } + } + +#endif // !COMPILE_DISABLE_DCC_VIDEO + return true; +} + +bool DccVideoThread::textStep() +{ +// qDebug("DccVideoThread::textStep()"); +#ifndef COMPILE_DISABLE_DCC_VIDEO + // Are we playing ? + if(m_bPlaying) + { + if(m_textInSignalBuffer.size() > 0) + { + KviDccThreadIncomingData data; + data.iLen = m_textInSignalBuffer.size(); + data.buffer = (char*) KviMemory::allocate(data.iLen); + memcpy(data.buffer, m_textInSignalBuffer.data(), data.iLen); + handleIncomingData(&data,false); + + m_textInSignalBuffer.clear(); + } + } + + // Are we recording ? + if(m_bRecording) + { + if(((DccVideoWindow*)parent())->m_tmpTextDataOut.size()) + { + m_textOutSignalBuffer.append((const unsigned char*) ((DccVideoWindow*)parent())->m_tmpTextDataOut.constData(), ((DccVideoWindow*)parent())->m_tmpTextDataOut.size()); + ((DccVideoWindow*)parent())->m_tmpTextDataOut.clear(); + } + + if(m_textOutSignalBuffer.size()) + m_pOpt->pCodec->encodeText(&m_textOutSignalBuffer,&m_outFrameBuffer); + } + +#endif // !COMPILE_DISABLE_DCC_VIDEO + return true; +} + +bool DccVideoThread::handleIncomingData(KviDccThreadIncomingData * data,bool bCritical) +{ +// qDebug("DccVideoThread::handleIncomingData"); + KVI_ASSERT(data->iLen); + KVI_ASSERT(data->buffer); + char * aux = data->buffer; + char * end = data->buffer + data->iLen; + while(aux != end) + { + if((*aux == '\n') || (*aux == '\0')) + { + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_DATA); + // The left part is len chars long + int len = aux - data->buffer; +// qDebug("LEN = %d, iLen = %d",len,data->iLen); +//#warning "DO IT BETTER (the \r cutting)" + KviCString * s = new KviCString(data->buffer,len); + if(s->lastCharIs('\r'))s->cutRight(1); + e->setData(s); + // but we cut also \n (or \0) + ++aux; + // so len += 1; --> new data->iLen -= len; + data->iLen -= (len + 1); +// qDebug("iLen now = %d",data->iLen); + KVI_ASSERT(data->iLen >= 0); + if(data->iLen > 0) + { + // memmove the remaining part to the beginning + // aux points after \n or \0 + KviMemory::move(data->buffer,aux,data->iLen); + data->buffer = (char *)KviMemory::reallocate(data->buffer,data->iLen); + end = data->buffer + data->iLen; + aux = data->buffer; + } else { + // no more data in the buffer + KVI_ASSERT(data->iLen == 0); + KviMemory::free(data->buffer); + data->buffer = end = aux = 0; + } + postEvent(parent(),e); + } else aux++; +// qDebug("PASSING CHAR %c",*aux); + } + // now aux == end + if(bCritical) + { + // need to flush everything... + if(data->iLen > 0) + { + // in the last part there are no NULL and \n chars + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_DATA); + KviCString * s = new KviCString(data->buffer,data->iLen); + if(s->lastCharIs('\r'))s->cutRight(1); + e->setData(s); + data->iLen = 0; + KviMemory::free(data->buffer); + data->buffer = 0; + postEvent(parent(),e); + } + } + return true; +} + +void DccVideoThread::restartRecording(int iDevice, int iInput, int) +{ +#ifndef COMPILE_DISABLE_DCC_VIDEO + m_bRecording=false; + if(!g_pVideoDevicePool) + g_pVideoDevicePool = Kopete::AV::VideoDevicePool::self(); + + g_pVideoDevicePool->stopCapturing(); + g_pVideoDevicePool->open(iDevice); + g_pVideoDevicePool->setSize(320, 240); + if(iInput >= 0) + g_pVideoDevicePool->selectInput(iInput); + g_pVideoDevicePool->startCapturing(); + + m_bRecording=true; +#endif +} + +void DccVideoThread::startRecording() +{ +#ifndef COMPILE_DISABLE_DCC_VIDEO + //qDebug("Start recording"); + if(m_bRecording)return; // already started + +// qDebug("Posting event"); + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); + e->setData(new int(KVI_DCC_VIDEO_THREAD_ACTION_START_RECORDING)); + postEvent(DccThread::parent(),e); + + m_bRecording = true; +#endif +} + +void DccVideoThread::stopRecording() +{ +#ifndef COMPILE_DISABLE_DCC_VIDEO + //qDebug("Stop recording"); + if(!m_bRecording)return; // already stopped + + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); + e->setData(new int(KVI_DCC_VIDEO_THREAD_ACTION_STOP_RECORDING)); + postEvent(DccThread::parent(),e); + + m_bRecording = false; +#endif +} + +void DccVideoThread::startPlaying() +{ +#ifndef COMPILE_DISABLE_DCC_VIDEO + //qDebug("Start playing"); + if(m_bPlaying)return; + + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); + e->setData(new int(KVI_DCC_VIDEO_THREAD_ACTION_START_PLAYING)); + postEvent(DccThread::parent(),e); + m_bPlaying = true; + +#endif +} + +void DccVideoThread::stopPlaying() +{ +#ifndef COMPILE_DISABLE_DCC_VIDEO + //qDebug("Stop playing"); + if(!m_bPlaying)return; + + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); + e->setData(new int(KVI_DCC_VIDEO_THREAD_ACTION_STOP_PLAYING)); + postEvent(DccThread::parent(),e); + m_bPlaying = false; +#endif +} + +void DccVideoThread::run() +{ +// qDebug("DccVideoThread::run()"); +#ifndef COMPILE_DISABLE_DCC_VIDEO + for(;;) + { + // Dequeue events + while(KviThreadEvent * e = dequeueEvent()) + { + if(e->id() == KVI_THREAD_EVENT_TERMINATE) + { + delete e; + goto exit_dcc; + } else if(e->id() == KVI_DCC_THREAD_EVENT_ACTION) + { + int * act = ((KviThreadDataEvent *)e)->getData(); + if(*act)startRecording(); + else stopRecording(); + delete act; + delete e; + } else { + // Other events are senseless to us + delete e; + } + } + + if(!readWriteStep())goto exit_dcc; + if(!videoStep())goto exit_dcc; + if(!textStep())goto exit_dcc; + + usleep(FRAME_DURATION*1000); +// qDebug("in %d out %d in_sig %d out_sig %d", m_inFrameBuffer.size(), m_outFrameBuffer.size(), m_videoInSignalBuffer.size(), m_videoOutSignalBuffer.size()); + } + + +exit_dcc: + +#endif //! COMPILE_DISABLE_DCC_VIDEO + kvi_socket_close(m_fd); + m_fd = KVI_INVALID_SOCKET; +} + +DccVideoWindow::DccVideoWindow(KviMainWindow *pFrm,DccDescriptor * dcc,const char * name) +: DccWindow(KVI_WINDOW_TYPE_DCCVIDEO,pFrm,name,dcc) +{ + m_pDescriptor = dcc; + m_pSlaveThread = 0; + m_pszTarget = 0; + + m_pLayout = new QGridLayout(this); + + m_pButtonBox = new KviTalHBox(this); + + m_pLabel = new KviThemedLabel(m_pButtonBox, this, "dcc_chat_label"); + m_pLabel->setText(name); + m_pButtonBox->setStretchFactor(m_pLabel,1); + + m_pButtonContainer= new KviTalHBox(m_pButtonBox); + createTextEncodingButton(m_pButtonContainer); + +#ifdef COMPILE_CRYPT_SUPPORT + createCryptControllerButton(m_pButtonContainer); +#endif + m_pLayout->addWidget(m_pButtonBox, 0, 0, 1, 3); + + m_pIrcView = new KviIrcView(this,pFrm,this); + connect(m_pIrcView,SIGNAL(rightClicked()),this,SLOT(textViewRightClicked())); + m_pInput = new KviInput(this); + + //remote video + m_pInVideoLabel = new QLabel(); + m_pInVideoLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_pInVideoLabel->setMinimumSize(320, 240); + m_pInVideoLabel->setFrameShape(QFrame::Box); + m_pInVideoLabel->setScaledContents(true); + m_pInVideoLabel->setAlignment(Qt::AlignCenter); + m_pLayout->addWidget(m_pInVideoLabel, 1, 0, 6, 1); + + //local video + m_pOutVideoLabel = new QLabel(); + m_pOutVideoLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_pOutVideoLabel->setMinimumSize(320, 240); + m_pOutVideoLabel->setFrameShape(QFrame::Box); + m_pOutVideoLabel->setScaledContents(true); + m_pOutVideoLabel->setAlignment(Qt::AlignCenter); + m_pLayout->addWidget(m_pOutVideoLabel, 1, 1, 6, 1); + + //local video input: config + m_pVideoLabel[0] = new QLabel(); + m_pVideoLabel[0]->setText(__tr2qs_ctx("Video device:","dcc")); + m_pLayout->addWidget(m_pVideoLabel[0], 1, 2, 1, 1); + + m_pCDevices = new QComboBox(); + m_pLayout->addWidget(m_pCDevices, 2, 2, 1, 1); + + m_pVideoLabel[1] = new QLabel(); + m_pVideoLabel[1]->setText(__tr2qs_ctx("Input:","dcc")); + m_pLayout->addWidget(m_pVideoLabel[1], 3, 2, 1, 1); + + m_pCInputs = new QComboBox(); + m_pLayout->addWidget(m_pCInputs, 4, 2, 1, 1); + + m_pVideoLabel[2] = new QLabel(); + m_pVideoLabel[2]->setText(__tr2qs_ctx("Standard:","dcc")); + m_pLayout->addWidget(m_pVideoLabel[2], 5, 2, 1, 1); + + m_pCStandards = new QComboBox(); + m_pLayout->addWidget(m_pCStandards, 6, 2, 1, 1); + + m_pLayout->addWidget(m_pIrcView, 7, 0, 1, 3); + m_pLayout->addWidget(m_pInput, 8, 0, 1, 3); + m_pLayout->setRowStretch(7,1); + + setLayout(m_pLayout); + + if(KVI_OPTION_BOOL(KviOption_boolAutoLogDccChat))m_pIrcView->startLogging(); + + connect(&m_Timer, SIGNAL(timeout()), this, SLOT(slotUpdateImage()) ); + + m_Timer.start(FRAME_DURATION); + + m_pMarshal = new DccMarshal(this); + connect(m_pMarshal,SIGNAL(error(int)),this,SLOT(handleMarshalError(int))); + connect(m_pMarshal,SIGNAL(connected()),this,SLOT(connected())); + connect(m_pMarshal,SIGNAL(inProgress()),this,SLOT(connectionInProgress())); + + connect(m_pCDevices, SIGNAL(currentIndexChanged(int)), this, SLOT(videoInputChanged(int))); + connect(m_pCInputs, SIGNAL(currentIndexChanged(int)), this, SLOT(videoInputChanged(int))); + connect(m_pCStandards, SIGNAL(currentIndexChanged(int)), this, SLOT(videoInputChanged(int))); + + startConnection(); +} + +DccVideoWindow::~DccVideoWindow() +{ + if(m_pInVideoLabel) + { + delete m_pInVideoLabel; + m_pInVideoLabel=0; + } + if(m_pOutVideoLabel) + { + delete m_pOutVideoLabel; + m_pOutVideoLabel=0; + } + if(m_pCDevices) + { + delete m_pCDevices; + m_pCDevices=0; + } + if(m_pCInputs) + { + delete m_pCInputs; + m_pCInputs=0; + } + if(m_pCStandards) + { + delete m_pCStandards; + m_pCStandards=0; + } + if(m_pVideoLabel[0]) + { + delete m_pVideoLabel[2]; + delete m_pVideoLabel[1]; + delete m_pVideoLabel[0]; + m_pVideoLabel[2] = 0; + m_pVideoLabel[1] = 0; + m_pVideoLabel[0] = 0; + } + if(m_pLayout) + { + delete m_pLayout; + m_pLayout=0; + } + + g_pDccBroker->unregisterDccWindow(this); + + if(m_pSlaveThread) + { + m_pSlaveThread->terminate(); + delete m_pSlaveThread; + m_pSlaveThread = 0; + } + + KviThreadManager::killPendingEvents(this); + + if(m_pszTarget) + { + delete m_pszTarget; + m_pszTarget = 0; + } +} + +void DccVideoWindow::textViewRightClicked() +{ + KVS_TRIGGER_EVENT_1(KviEvent_OnDCCChatPopupRequest,this,m_pDescriptor->idString()); +} + +void DccVideoWindow::triggerCreationEvents() +{ + KVS_TRIGGER_EVENT_1(KviEvent_OnDCCChatWindowCreated,this,m_pDescriptor->idString()); +} + +void DccVideoWindow::triggerDestructionEvents() +{ + KVS_TRIGGER_EVENT_1(KviEvent_OnDCCChatWindowClosing,this,m_pDescriptor->idString()); +} + +void DccVideoWindow::startConnection() +{ + if(!(m_pDescriptor->bActive)) + { + // PASSIVE CONNECTION + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Attempting a passive DCC VIDEO connection","dcc")); + KviError::Code eError = m_pMarshal->dccListen(m_pDescriptor->szListenIp,m_pDescriptor->szListenPort,m_pDescriptor->bDoTimeout); + if(eError != KviError::Success) + handleMarshalError(eError); + } else { + // ACTIVE CONNECTION + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Attempting an active DCC VIDEO connection","dcc")); + KviError::Code eError = m_pMarshal->dccConnect(m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data(),m_pDescriptor->bDoTimeout); + if(eError != KviError::Success) + handleMarshalError(eError); + } +} + +void DccVideoWindow::connectionInProgress() +{ + if(m_pDescriptor->bActive) + { + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Contacting host %Q on port %Q","dcc"),&(m_pDescriptor->szIp),&(m_pDescriptor->szPort)); + } else { + + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Listening on interface %Q port %Q","dcc"), + &(m_pMarshal->localIp()),&(m_pMarshal->localPort())); + + if(m_pDescriptor->bSendRequest) + { + QString ip = !m_pDescriptor->szFakeIp.isEmpty() ? m_pDescriptor->szFakeIp : m_pDescriptor->szListenIp; + KviCString port = !m_pDescriptor->szFakePort.isEmpty() ? m_pDescriptor->szFakePort : m_pMarshal->localPort(); +//#warning "OPTION FOR SENDING 127.0.0.1 and so on (not an unsigned nuumber)" + struct in_addr a; + if(KviNetUtils::stringIpToBinaryIp(ip,&a)) { + ip.setNum(htonl(a.s_addr)); + } + + m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC VIDEO %s %Q %s %d%c", + m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(), + 0x01,m_pDescriptor->szCodec.ptr(), + &ip,port.ptr(),m_pDescriptor->iSampleRate,0x01); + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Sent DCC VIDEO (%s) request to %Q, waiting for the remote client to connect...","dcc"), + m_pDescriptor->szCodec.ptr(),&(m_pDescriptor->szNick)); + } else output(KVI_OUT_DCCMSG,__tr2qs_ctx("DCC VIDEO request not sent: awaiting manual connection","dcc")); + } +} + +const QString & DccVideoWindow::target() +{ + // This may change on the fly... + if(!m_pszTarget) + m_pszTarget = new QString(); + + m_pszTarget->sprintf("%s@%s:%s",m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data()); + return *m_pszTarget; +} + +void DccVideoWindow::getBaseLogFileName(QString &buffer) +{ + buffer.sprintf("dccvideo_%s_%s_%s",m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szLocalFileName.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data()); +} + +void DccVideoWindow::fillCaptionBuffers() +{ + KviCString tmp(KviCString::Format,"DCC Video %s@%s:%s %s", + m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data(), + m_pDescriptor->szLocalFileName.toUtf8().data()); + + m_szPlainTextCaption = tmp; +} + +QPixmap * DccVideoWindow::myIconPtr() +{ + return g_pIconManager->getSmallIcon(KVI_SMALLICON_DCCVOICE); +} + +void DccVideoWindow::ownMessage(const QString &text, bool bUserFeedback) +{ + if(!m_pSlaveThread) + { + output(KVI_OUT_SYSTEMWARNING,__tr2qs_ctx("Cannot send data: No active connection","dcc")); + return; + } + + QByteArray szData = encodeText(text); + const char * d = szData.data(); + if(!d)return; + +#ifdef COMPILE_CRYPT_SUPPORT + if(cryptSessionInfo()) + { + if(cryptSessionInfo()->m_bDoEncrypt) + { + if(*d != KviMircCntrl::CryptEscape) + { + KviCString encrypted; + cryptSessionInfo()->m_pEngine->setMaxEncryptLen(-1); + switch(cryptSessionInfo()->m_pEngine->encrypt(d,encrypted)) + { + case KviCryptEngine::Encrypted: + { + KviCString buf(KviCString::Format,"%s\r\n",encrypted.ptr()); + m_tmpTextDataOut.append(buf.ptr(), buf.len()); + if(bUserFeedback) + m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSGCRYPTED, + m_pDescriptor->szLocalNick.toUtf8().data(),m_pDescriptor->szLocalUser.toUtf8().data(), + m_pDescriptor->szLocalHost.toUtf8().data(),text,KviConsoleWindow::NoNotifications); + } + break; + case KviCryptEngine::Encoded: + { + KviCString buf(KviCString::Format,"%s\r\n",encrypted.ptr()); + m_tmpTextDataOut.append(buf.ptr(), buf.len()); + if(bUserFeedback) + { + QString encr = decodeText(encrypted.ptr()); + m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG, + m_pDescriptor->szLocalNick.toUtf8().data(),m_pDescriptor->szLocalUser.toUtf8().data(), + m_pDescriptor->szLocalHost.toUtf8().data(),encr,KviConsoleWindow::NoNotifications); + } + } + break; + default: // also case KviCryptEngine::EncryptError + { + QString szErr = cryptSessionInfo()->m_pEngine->lastError(); + output(KVI_OUT_SYSTEMERROR, + __tr2qs_ctx("The crypto engine was not able to encrypt the current message (%Q): %Q, no data was sent to the remote end","dcc"), + &text,&szErr); + } + break; + } + return; + } else { + d++; //eat the escape code + KviCString buf(KviCString::Format,"%s\r\n",d); + QString tmp = text.right(text.length() - 1); + m_tmpTextDataOut.append(buf.ptr(), buf.len()); + + if(bUserFeedback) + m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG, + m_pDescriptor->szLocalNick.toUtf8().data(),m_pDescriptor->szLocalUser.toUtf8().data(), + m_pDescriptor->szLocalHost.toUtf8().data(),tmp,KviConsoleWindow::NoNotifications); + return; + } + } + } +#endif + KviCString buf(KviCString::Format,"%s\r\n",d); + m_tmpTextDataOut.append(buf.ptr(), buf.len()); + + if(bUserFeedback) + m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG, + m_pDescriptor->szLocalNick.toUtf8().data(),m_pDescriptor->szLocalUser.toUtf8().data(), + m_pDescriptor->szLocalHost.toUtf8().data(),text,KviConsoleWindow::NoNotifications); +} + +const QString & DccVideoWindow::localNick() +{ + // FIXME: This is just a complete HACK + m_szLocalNick = m_pDescriptor->szLocalNick; + return m_szLocalNick; +} + +void DccVideoWindow::ownAction(const QString &text) +{ + if(m_pSlaveThread) + { + QString szTmpBuffer; + //see bug ticket #220 + if(KVI_OPTION_BOOL(KviOption_boolStripMircColorsInUserMessages)) + { + szTmpBuffer = KviMircCntrl::stripControlBytes(text); + } else { + szTmpBuffer = text; + } + + QByteArray szData = encodeText(szTmpBuffer); + const char * d = szData.data(); + if(!d)return; + KviCString buf(KviCString::Format,"%cACTION %s%c\r\n",0x01,d,0x01); + m_tmpTextDataOut.append(buf.ptr(), buf.len()); + output(KVI_OUT_ACTION,"%Q %Q",&(m_pDescriptor->szLocalNick),&szTmpBuffer); + } else { + output(KVI_OUT_SYSTEMWARNING,__tr2qs_ctx("Cannot send data: No active connection","dcc")); + } +} + +bool DccVideoWindow::event(QEvent *e) +{ + if(e->type() == KVI_THREAD_EVENT) + { + switch(((KviThreadEvent *)e)->id()) + { + case KVI_DCC_THREAD_EVENT_ERROR: + { + KviError::Code * pError = ((KviThreadDataEvent *)e)->getData(); + QString ssss = KviError::getDescription(*pError); + output(KVI_OUT_DCCERROR,__tr2qs_ctx("ERROR: %Q","dcc"),&(ssss)); + delete pError; + return true; + } + break; + case KVI_DCC_THREAD_EVENT_DATA: + { + KviCString * encoded = ((KviThreadDataEvent *)e)->getData(); + KviCString d=KviCString(decodeText(encoded->ptr())); + if(d.firstCharIs(0x01)) + { + d.cutLeft(1); + if(d.lastCharIs(0x01)) + d.cutRight(1); + if(kvi_strEqualCIN("ACTION",d.ptr(),6)) + d.cutLeft(6); + d.stripLeftWhiteSpace(); + output(KVI_OUT_ACTION,"%Q %s",&(m_pDescriptor->szNick),d.ptr()); + if(!hasAttention()) + { + if(KVI_OPTION_BOOL(KviOption_boolFlashDccChatWindowOnNewMessages)) + { + demandAttention(); + } + if(KVI_OPTION_BOOL(KviOption_boolPopupNotifierOnNewDccChatMessages)) + { + QString szMsg = ""; + szMsg += m_pDescriptor->szNick; + szMsg += " "; + szMsg += Qt::escape(QString(d.ptr())); + //qDebug("KviIrcServerParser_ctcp.cpp:975 debug: %s",szMsg.data()); + g_pApp->notifierMessage(this,KVI_OPTION_MSGTYPE(KVI_OUT_ACTION).pixId(),szMsg,KVI_OPTION_UINT(KviOption_uintNotifierAutoHideTime)); + } + } + } else { + +#ifdef COMPILE_CRYPT_SUPPORT + if(KviCryptSessionInfo * cinf = cryptSessionInfo()) + { + if(cinf->m_bDoDecrypt) + { + KviCString decryptedStuff; + switch(cinf->m_pEngine->decrypt(d.ptr(),decryptedStuff)) + { + case KviCryptEngine::DecryptOkWasEncrypted: + case KviCryptEngine::DecryptOkWasEncoded: + case KviCryptEngine::DecryptOkWasPlainText: + if(!KVS_TRIGGER_EVENT_2_HALTED(KviEvent_OnDCCChatMessage,this,QString(decryptedStuff.ptr()),m_pDescriptor->idString())) + { + m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG, + m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szUser.toUtf8().data(), + m_pDescriptor->szHost.toUtf8().data(),decryptedStuff.ptr()); + } + delete encoded; + return true; + break; + + default: // also case KviCryptEngine::DecryptError + { + QString szErr = cinf->m_pEngine->lastError(); + output(KVI_OUT_SYSTEMERROR, + __tr2qs_ctx("The following message appears to be encrypted, but the crypto engine failed to decode it: %Q","dcc"), + &szErr); + } + break; + } + } + } else { +#endif + // FIXME! + if(!KVS_TRIGGER_EVENT_2_HALTED(KviEvent_OnDCCChatMessage,this,QString(d.ptr()),m_pDescriptor->idString())) + { + m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG, + m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szUser.toUtf8().data(), + m_pDescriptor->szHost.toUtf8().data(),d.ptr()); + if(!hasAttention()) + { + if(KVI_OPTION_BOOL(KviOption_boolFlashDccChatWindowOnNewMessages)) + { + demandAttention(); + } + if(KVI_OPTION_BOOL(KviOption_boolPopupNotifierOnNewDccChatMessages)) + { + QString szMsg = Qt::escape(QString(d.ptr())); + g_pApp->notifierMessage(this,KVI_SMALLICON_DCCCHATMSG,szMsg,KVI_OPTION_UINT(KviOption_uintNotifierAutoHideTime)); + } + } + } +#ifdef COMPILE_CRYPT_SUPPORT + } +#endif + } + delete encoded; + return true; + } + + case KVI_DCC_THREAD_EVENT_MESSAGE: + { + KviCString * str = ((KviThreadDataEvent *)e)->getData(); + outputNoFmt(KVI_OUT_DCCMSG,__tr_no_xgettext_ctx(str->ptr(),"dcc")); + delete str; + return true; + } + break; + case KVI_DCC_THREAD_EVENT_ACTION: + { + int * act = ((KviThreadDataEvent *)e)->getData(); + switch(*act) + { + case KVI_DCC_VIDEO_THREAD_ACTION_START_RECORDING: +// m_pRecordingLabel->setEnabled(true); + break; + case KVI_DCC_VIDEO_THREAD_ACTION_STOP_RECORDING: +// m_pRecordingLabel->setEnabled(false); + break; + case KVI_DCC_VIDEO_THREAD_ACTION_START_PLAYING: +// m_pPlayingLabel->setEnabled(true); + break; + case KVI_DCC_VIDEO_THREAD_ACTION_STOP_PLAYING: +// m_pPlayingLabel->setEnabled(false); + break; + } + delete act; + return true; + } + break; + default: + qDebug("Invalid event type %d received",((KviThreadEvent *)e)->id()); + break; + } + + } + + return KviWindow::event(e); +} + +void DccVideoWindow::handleMarshalError(KviError::Code eError) +{ + QString ssss = KviError::getDescription(eError); + output(KVI_OUT_DCCERROR,__tr2qs_ctx("DCC Failed: %Q","dcc"),&ssss); +} + +void DccVideoWindow::connected() +{ + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Connected to %Q:%Q","dcc"), + &(m_pMarshal->remoteIp()),&(m_pMarshal->remotePort())); + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Local end is %Q:%Q","dcc"), + &(m_pMarshal->localIp()),&(m_pMarshal->localPort())); + if(!(m_pDescriptor->bActive)) + { + m_pDescriptor->szIp = m_pMarshal->remoteIp(); + m_pDescriptor->szPort = m_pMarshal->remotePort(); + m_pDescriptor->szHost = m_pMarshal->remoteIp(); + } + updateCaption(); + + KviDccVideoThreadOptions * opt = new KviDccVideoThreadOptions; + + opt->pCodec = kvi_dcc_video_get_codec(m_pDescriptor->szCodec.ptr()); + + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Actual codec used is '%s'","dcc"),opt->pCodec->name()); + + m_pSlaveThread = new DccVideoThread(this,m_pMarshal->releaseSocket(),opt); + +#ifndef COMPILE_DISABLE_DCC_VIDEO + if(g_pVideoDevicePool) + { + g_pVideoDevicePool->fillDeviceQComboBox(m_pCDevices); + g_pVideoDevicePool->fillInputQComboBox(m_pCInputs); + g_pVideoDevicePool->fillStandardQComboBox(m_pCStandards); + + connect(g_pVideoDevicePool, SIGNAL(deviceRegistered(const QString &) ), SLOT(deviceRegistered(const QString &)) ); + connect(g_pVideoDevicePool, SIGNAL(deviceUnregistered(const QString &) ), SLOT(deviceUnregistered(const QString &)) ); + } +#endif + + m_pSlaveThread->start(); +} + +void DccVideoWindow::stopTalking() +{ + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); + e->setData(new int(0)); + m_pSlaveThread->enqueueEvent(e); +} + +void DccVideoWindow::startTalking() +{ + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); + e->setData(new int(1)); + m_pSlaveThread->enqueueEvent(e); +} + +void DccVideoWindow::startOrStopTalking(bool bStart) +{ + if(bStart)startTalking(); + else stopTalking(); +} + +void DccVideoWindow::slotUpdateImage() +{ +#ifndef COMPILE_DISABLE_DCC_VIDEO + if(m_pSlaveThread && isVisible()) + { + m_pOutVideoLabel->setPixmap(QPixmap::fromImage(m_pSlaveThread->m_outImage)); + m_pInVideoLabel->setPixmap(QPixmap::fromImage(m_pSlaveThread->m_inImage)); + } +#endif +} + +void DccVideoWindow::deviceRegistered(const QString &) +{ + +#ifndef COMPILE_DISABLE_DCC_VIDEO + g_pVideoDevicePool->fillDeviceQComboBox(m_pCDevices); + g_pVideoDevicePool->fillInputQComboBox(m_pCInputs); + g_pVideoDevicePool->fillStandardQComboBox(m_pCStandards); + + // update the mVideoImageLabel to show the camera frames + g_pVideoDevicePool->open(); + g_pVideoDevicePool->setSize(320, 240); + g_pVideoDevicePool->startCapturing(); + +// setVideoInputParameters(); + +// if ( g_pVideoDevicePool->hasDevices() ) +// { +// m_Timer.start(200); //5fps +// } +#endif +} + + +void DccVideoWindow::deviceUnregistered(const QString & ) +{ +#ifndef COMPILE_DISABLE_DCC_VIDEO + g_pVideoDevicePool->fillDeviceQComboBox(m_pCDevices); + g_pVideoDevicePool->fillInputQComboBox(m_pCInputs); + g_pVideoDevicePool->fillStandardQComboBox(m_pCStandards); +#endif +} + +void DccVideoWindow::videoInputChanged(int ) +{ + if(m_pSlaveThread) + m_pSlaveThread->restartRecording(m_pCDevices->currentIndex(), m_pCInputs->currentIndex(), m_pCStandards->currentIndex()); +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_DccVideoWindow.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/dcc/DccVideoWindow.h b/src/modules/dcc/DccVideoWindow.h new file mode 100644 index 000000000..b0cc2c7f4 --- /dev/null +++ b/src/modules/dcc/DccVideoWindow.h @@ -0,0 +1,158 @@ +#ifndef _VIDEO_H_ +#define _VIDEO_H_ +//============================================================================= +// +// File : DccVideoWindow.h +// Creation date : Tue Nov 10 18:08:09 2009 GMT by Fabio Bas +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2009 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "DccVoiceCodec.h" +#include "DccDescriptor.h" +#include "DccThread.h" +#include "DccWindow.h" + +#include "KviWindow.h" +#include "KviDataBuffer.h" +#include "kvi_sockettype.h" +#include "KviTalHBox.h" +#include "KviThemedLabel.h" +#include "KviError.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifndef COMPILE_DISABLE_DCC_VIDEO + #include "avdevice/videodevicepool.h" +#endif + +#ifdef COMPILE_CRYPT_SUPPORT + class KviCryptSessionInfo; +#endif + +class QSlider; +class DccMarshal; + +#ifndef _DCC_VIDEO_CPP_ + extern bool kvi_dcc_video_is_valid_codec(const char * codecName); +#endif + +#define KVI_DCC_VIDEO_THREAD_ACTION_START_RECORDING 0 +#define KVI_DCC_VIDEO_THREAD_ACTION_STOP_RECORDING 1 +#define KVI_DCC_VIDEO_THREAD_ACTION_START_PLAYING 2 +#define KVI_DCC_VIDEO_THREAD_ACTION_STOP_PLAYING 3 + +typedef struct _KviDccVideoThreadOptions +{ + QString szVideoDevice; + DccVideoCodec * pCodec; +} KviDccVideoThreadOptions; + +class DccVideoThread : public DccThread +{ + friend class DccVideoWindow; +public: + DccVideoThread(KviWindow * wnd,kvi_socket_t fd,KviDccVideoThreadOptions * opt); + ~DccVideoThread(); +protected: + KviDccVideoThreadOptions * m_pOpt; + KviDataBuffer m_outFrameBuffer; + KviDataBuffer m_inFrameBuffer; + KviDataBuffer m_videoInSignalBuffer; + KviDataBuffer m_textInSignalBuffer; + KviDataBuffer m_videoOutSignalBuffer; + KviDataBuffer m_textOutSignalBuffer; + bool m_bPlaying; + bool m_bRecording; +protected: + QImage m_inImage; + QImage m_outImage; +protected: + bool readWriteStep(); + bool videoStep(); + bool textStep(); + void startRecording(); + void restartRecording(int iDevice, int iInput, int iStandard); + void stopRecording(); + void startPlaying(); + void stopPlaying(); + inline bool isPlaying() { return m_bPlaying; }; + virtual void run(); + virtual bool handleIncomingData(KviDccThreadIncomingData *data,bool bCritical); +}; + + +class DccVideoWindow : public DccWindow +{ + Q_OBJECT + friend class DccVideoThread; +public: + DccVideoWindow(KviMainWindow *pFrm,DccDescriptor * dcc,const char * name); + ~DccVideoWindow(); +protected: + KviThemedLabel * m_pLabel; + KviTalHBox * m_pButtonBox; + KviTalHBox * m_pButtonContainer; + + QLabel * m_pInVideoLabel; + QLabel * m_pOutVideoLabel; + QComboBox * m_pCDevices; + QComboBox * m_pCInputs; + QComboBox * m_pCStandards; + QGridLayout * m_pLayout; + QTimer m_Timer; + QLabel * m_pVideoLabel[2]; + QString * m_pszTarget; + DccVideoThread * m_pSlaveThread; + QByteArray m_tmpTextDataOut; + QString m_szLocalNick; +protected: + virtual void triggerCreationEvents(); + virtual void triggerDestructionEvents(); + virtual const QString & target(); + virtual void fillCaptionBuffers(); + virtual QPixmap * myIconPtr(); + virtual bool event(QEvent *e); + virtual void getBaseLogFileName(QString &buffer); + void startTalking(); + void stopTalking(); + void startConnection(); + virtual const QString & localNick(); + virtual void ownMessage(const QString &text, bool bUserFeedback = true); + virtual void ownAction(const QString &text); +protected slots: + void handleMarshalError(KviError::Code eError); + void connected(); + void startOrStopTalking(bool bStart); + void connectionInProgress(); + void slotUpdateImage(); + void deviceRegistered(const QString &); + void deviceUnregistered(const QString &); + void textViewRightClicked(); + void videoInputChanged(int ); +}; + + +#endif //_VOICE_H_ diff --git a/src/modules/dcc/DccVoiceAdpcmCodec.cpp b/src/modules/dcc/DccVoiceAdpcmCodec.cpp new file mode 100644 index 000000000..043797359 --- /dev/null +++ b/src/modules/dcc/DccVoiceAdpcmCodec.cpp @@ -0,0 +1,306 @@ +//============================================================================= +// +// File : DccVoiceAdpcmCodec.h +// Creation date : Wed Aug 22 19:12:46 2001 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= +// +// Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The Netherlands. +// All Rights Reserved +// +// Permission to use, copy, modify, and distribute this software and its +// documentation for any purpose and without fee is hereby granted, +// provided that the above copyright notice appear in all copies and that +// both that copyright notice and this permission notice appear in +// supporting documentation, and that the names of Stichting Mathematisch +// Centrum or CWI not be used in advertising or publicity pertaining to +// distribution of the software without specific, written prior permission. +// +// STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO +// THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE +// FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +// OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// +// +// Intel/DVI ADPCM coder/decoder. +// +// The algorithm for this coder was taken from the IMA Compatability Project +// proceedings, Vol 2, Number 2; May 1992. +// +// Version 1.2, 18-Dec-92. +// + +#define _ADPCMCODEC_CPP_ +#include "DccVoiceAdpcmCodec.h" + +#include /*DBG*/ + +#ifndef __STDC__ + #define signed +#endif + + + +#define ADPCM_PACKED_FRAME_SIZE_IN_BYTES 512 +#define ADPCM_UNPACKED_FRAME_SIZE_IN_BYTES 2048 +#define ADPCM_UNPACKED_FRAME_SIZE_IN_SHORTS 1024 + +// Intel ADPCM step variation table */ +static int indexTable[16] = { + -1, -1, -1, -1, 2, 4, 6, 8, + -1, -1, -1, -1, 2, 4, 6, 8, +}; + +static int stepsizeTable[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 +}; + +void ADPCM_compress(short indata[],char outdata[],int len,ADPCM_state *state) +{ + short *lpIn; /* Input buffer pointer */ + signed char *lpOut; /* output buffer pointer */ + int val; /* Current input sample value */ + int sign; /* Current adpcm sign bit */ + int delta; /* Current adpcm output value */ + int diff; /* Difference between val and valprev */ + int step; /* Stepsize */ + int valpred; /* Predicted output value */ + int vpdiff; /* Current change to valpred */ + int index; /* Current step change index */ + int outputbuffer = 0; /* place to keep previous 4-bit value */ + int bufferstep; /* toggle between outputbuffer/output */ + + lpOut = (signed char *)outdata; + lpIn = indata; + + valpred = state->valprev; + index = state->index; + step = stepsizeTable[index]; + + bufferstep = 1; + + for ( ;len > 0;len-- ) { + val = *lpIn++; + // Step 1 - compute difference with previous value + diff = val - valpred; + sign = (diff < 0) ? 8 : 0; + if(sign)diff=(-diff); + // Step 2 - Divide and clamp + // Note: + // This code *approximately* computes: + // delta = diff*4/step; + // vpdiff = (delta+0.5)*step/4; + // but in shift step bits are dropped. The net result of this is + // that even if you have fast mul/div hardware you cannot put it to + // good use since the fixup would be too expensive. + // + delta = 0; + vpdiff = (step >> 3); + if (diff >=step){ + delta = 4; + diff -= step; + vpdiff += step; + } + step >>= 1; + if (diff >= step) { + delta |= 2; + diff -= step; + vpdiff += step; + } + step >>= 1; + if ( diff >= step ) { + delta |= 1; + vpdiff += step; + } + // Step 3 - Update previous value + if(sign)valpred -= vpdiff; + else valpred += vpdiff; + // Step 4 - Clamp previous value to 16 bits + if ( valpred > 32767 )valpred = 32767; + else if ( valpred < -32768 )valpred = -32768; + // Step 5 - Assemble value, update index and step values + delta |= sign; + index += indexTable[delta]; + if ( index < 0 ) index = 0; + if ( index > 88 ) index = 88; + step = stepsizeTable[index]; + // Step 6 - Output value + if ( bufferstep )outputbuffer = (delta << 4) & 0xf0; + else *lpOut++ = (delta & 0x0f) | outputbuffer; + bufferstep = !bufferstep; + } + // Output last step, if needed + if (!bufferstep)*lpOut++ = outputbuffer; + state->valprev = valpred; + state->index = index; +} + +void ADPCM_uncompress(char indata[],short outdata[],int len,ADPCM_state *state) +{ + signed char *inp; /* Input buffer pointer */ + short *outp; /* output buffer pointer */ + int sign; /* Current adpcm sign bit */ + int delta; /* Current adpcm output value */ + int step; /* Stepsize */ + int valpred; /* Predicted value */ + int vpdiff; /* Current change to valpred */ + int index; /* Current step change index */ + int inputbuffer=0; /* place to keep next 4-bit value */ + int bufferstep; /* toggle between inputbuffer/input */ + + outp = outdata; + inp = (signed char *)indata; + + valpred = state->valprev; + index = state->index; + step = stepsizeTable[index]; + + bufferstep = 0; + + for ( ; len > 0 ; len-- ) { + /* Step 1 - get the delta value */ + if ( bufferstep )delta = inputbuffer & 0xf; + else { + inputbuffer = *inp++; + delta = (inputbuffer >> 4) & 0xf; + } + bufferstep = !bufferstep; + + /* Step 2 - Find new index value (for later) */ + index += indexTable[delta]; + if ( index < 0 ) index = 0; + if ( index > 88 ) index = 88; + + /* Step 3 - Separate sign and magnitude */ + sign = delta & 8; + delta = delta & 7; + + /* Step 4 - Compute difference and new predicted value */ + /* + ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment + ** in adpcm_coder. + */ + vpdiff = step >> 3; + if( delta & 4 )vpdiff += step; + if( delta & 2 )vpdiff += step>>1; + if( delta & 1 )vpdiff += step>>2; + + if(sign)valpred -= vpdiff; + else valpred += vpdiff; + + /* Step 5 - clamp output value */ + if(valpred > 32767)valpred = 32767; + else if(valpred < -32768)valpred = -32768; + + /* Step 6 - Update step value */ + step = stepsizeTable[index]; + + /* Step 7 - Output value */ + *outp++ = valpred; + } + + state->valprev = valpred; + state->index = index; +} + + +DccVoiceAdpcmCodec::DccVoiceAdpcmCodec() +: DccVoiceCodec() +{ + m_pEncodeState = new ADPCM_state; + m_pEncodeState->index = 0; + m_pEncodeState->valprev = 0; + m_pDecodeState = new ADPCM_state; + m_pDecodeState->index = 0; + m_pDecodeState->valprev = 0; + m_szName = "adpcm (compression 1:4)"; +} + +DccVoiceAdpcmCodec::~DccVoiceAdpcmCodec() +{ + delete m_pEncodeState; + delete m_pDecodeState; +} + +void DccVoiceAdpcmCodec::encode(KviDataBuffer * signal,KviDataBuffer * stream) +{ + if(signal->size() < ADPCM_UNPACKED_FRAME_SIZE_IN_BYTES)return; // nothing to encode + + char * ptr = (char *)signal->data(); + + int uFrames = signal->size() / ADPCM_UNPACKED_FRAME_SIZE_IN_BYTES; + int uTotalDataCompressed = uFrames * ADPCM_UNPACKED_FRAME_SIZE_IN_BYTES; + int uFrameOffset = stream->size(); + char * endPtr = ptr + uTotalDataCompressed; + + stream->addSize(ADPCM_PACKED_FRAME_SIZE_IN_BYTES * uFrames); + + while(ptr != endPtr) + { + ADPCM_compress((short *)ptr,(char *)(stream->data() + uFrameOffset),ADPCM_UNPACKED_FRAME_SIZE_IN_SHORTS,m_pEncodeState); + ptr += ADPCM_UNPACKED_FRAME_SIZE_IN_BYTES; + uFrameOffset += ADPCM_PACKED_FRAME_SIZE_IN_BYTES; + } + signal->remove(uTotalDataCompressed); +} + +void DccVoiceAdpcmCodec::decode(KviDataBuffer * stream,KviDataBuffer * signal) +{ + if(stream->size() < ADPCM_PACKED_FRAME_SIZE_IN_BYTES)return; // nothing to decode + + char * ptr = (char *)stream->data(); + + // Adpcm codec + int uFrames = stream->size() / ADPCM_PACKED_FRAME_SIZE_IN_BYTES; + int uTotalDataDecompressed = uFrames * ADPCM_PACKED_FRAME_SIZE_IN_BYTES; + int uSignalOffset = signal->size(); + char * endPtr = ptr + (uTotalDataDecompressed); + + signal->addSize(ADPCM_UNPACKED_FRAME_SIZE_IN_BYTES * uFrames); + + while(ptr != endPtr) + { + ADPCM_uncompress((char *)ptr,(short *)(signal->data() + uSignalOffset),ADPCM_UNPACKED_FRAME_SIZE_IN_SHORTS,m_pDecodeState); + ptr += ADPCM_PACKED_FRAME_SIZE_IN_BYTES; + uSignalOffset += ADPCM_UNPACKED_FRAME_SIZE_IN_BYTES; + } + stream->remove(uTotalDataDecompressed); +} + +int DccVoiceAdpcmCodec::encodedFrameSize() +{ + return ADPCM_PACKED_FRAME_SIZE_IN_BYTES; +} + +int DccVoiceAdpcmCodec::decodedFrameSize() +{ + return ADPCM_UNPACKED_FRAME_SIZE_IN_BYTES; +} diff --git a/src/modules/dcc/DccVoiceAdpcmCodec.h b/src/modules/dcc/DccVoiceAdpcmCodec.h new file mode 100644 index 000000000..d993ecb68 --- /dev/null +++ b/src/modules/dcc/DccVoiceAdpcmCodec.h @@ -0,0 +1,73 @@ +#ifndef _ADPCMCODEC_H_ +#define _ADPCMCODEC_H_ +//============================================================================= +// +// File : DccVoiceAdpcmCodec.h +// Creation date : Wed Aug 22 19:12:46 2001 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= +// +// adpcm.h - include file for adpcm coder. +// +// Version 1.0, 7-Jul-92. +// +// +// Average compression speed experiment: P166MMX 32MEG +// +// INPUT | OUTPUT | COMPRESSION TIME +// ------------------------------------------------------------------------ +// shorts bytes | bytes | min msec. avrg. high peak (1 time) +// ------------------------------------------------------------------------ +// 512 1024 | 256 | ~4 4 34 +// 1024 2048 | 512 | ~7 8 75 +// 2048 4096 | 1024 | ~13 15 175 (!!!) +// 4096 8192 | 2048 | ~26 33 91 +// 8192 16384 | 4096 | ~57 80 220 (~1 sec of audio) +// 16384 32768 | 8192 | ~110 250 290 +// + +#include // fix for qtextstream.h + +#include "DccVoiceCodec.h" + +typedef struct adpcm_state +{ + short valprev; /* Previous output value */ + char index; /* HelpIndex into stepsize table */ +} ADPCM_state; + + +class DccVoiceAdpcmCodec : public DccVoiceCodec +{ +public: + DccVoiceAdpcmCodec(); + virtual ~DccVoiceAdpcmCodec(); +private: + ADPCM_state * m_pEncodeState; + ADPCM_state * m_pDecodeState; +public: + virtual void encode(KviDataBuffer * signal,KviDataBuffer * stream); + virtual void decode(KviDataBuffer * stream,KviDataBuffer * signal); + virtual int encodedFrameSize(); + virtual int decodedFrameSize(); +}; + + +#endif //_ADPCMCODEC_H_ diff --git a/src/modules/dcc/DccVoiceCodec.cpp b/src/modules/dcc/DccVoiceCodec.cpp new file mode 100644 index 000000000..76491d14c --- /dev/null +++ b/src/modules/dcc/DccVoiceCodec.cpp @@ -0,0 +1,327 @@ +//============================================================================= +// +// File : DccVoiceCodec.cpp +// Creation date : Sun Aug 26 04:19:36 2001 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "DccVoiceCodec.h" + + +#include +#include +#include + +DccVoiceCodec::DccVoiceCodec() +{ +} + +DccVoiceCodec::~DccVoiceCodec() +{ +} + +void DccVoiceCodec::encode(KviDataBuffer *,KviDataBuffer *) +{ +} + +void DccVoiceCodec::decode(KviDataBuffer *,KviDataBuffer *) +{ +} + +int DccVoiceCodec::encodedFrameSize() +{ + return 0; +} + +int DccVoiceCodec::decodedFrameSize() +{ + return 0; +} + +const char * DccVoiceCodec::name() +{ + return m_szName.ptr(); +} + +DccVoiceNullCodec::DccVoiceNullCodec() +: DccVoiceCodec() +{ + m_szName = "null (no compression)"; +} + +DccVoiceNullCodec::~DccVoiceNullCodec() +{ +} + +void DccVoiceNullCodec::encode(KviDataBuffer * signal,KviDataBuffer * stream) +{ + if(signal->size() < 1)return; + stream->append(signal->data(),signal->size()); + signal->resize(0); +} + +void DccVoiceNullCodec::decode(KviDataBuffer * stream,KviDataBuffer * signal) +{ + if(stream->size() < 1)return; + signal->append(stream->data(),stream->size()); + + stream->resize(0); +} + +int DccVoiceNullCodec::encodedFrameSize() +{ + return 1024; +} + +int DccVoiceNullCodec::decodedFrameSize() +{ + return 1024; +} + +//-------------------------- + +DccVideoCodec::DccVideoCodec() +{ +} + +DccVideoCodec::~DccVideoCodec() +{ +} + +void DccVideoCodec::encodeVideo(KviDataBuffer *,KviDataBuffer *) +{ +} + +void DccVideoCodec::encodeText(KviDataBuffer *,KviDataBuffer *) +{ +} + +void DccVideoCodec::decode(KviDataBuffer *,KviDataBuffer *,KviDataBuffer *) +{ +} + +int DccVideoCodec::encodedFrameSize() +{ + return 0; +} + +int DccVideoCodec::decodedFrameSize() +{ + return 0; +} + +const char * DccVideoCodec::name() +{ + return m_szName.ptr(); +} + +DccVideoSJpegCodec::DccVideoSJpegCodec() +: DccVideoCodec() +{ + m_szName = "sjpeg"; +} + +DccVideoSJpegCodec::~DccVideoSJpegCodec() +{ +} + +void DccVideoSJpegCodec::encodeVideo(KviDataBuffer * videoSignal,KviDataBuffer * stream) +{ + + if(videoSignal->size() < 1) return; + + QImage img(videoSignal->data(), 320, 240, 1280, QImage::Format_ARGB32); + QByteArray ba; + QBuffer buffer(&ba); + buffer.open(QIODevice::WriteOnly); + //0 to obtain small compressed files, + //100 for large uncompressed files, + //and -1 (the default) to use the default settings. + img.save(&buffer, "JPEG", 20); + if(ba.size() > 0) + { + stream->append((const unsigned char*)ba.data(),ba.size()); + } + videoSignal->clear(); +} + +void DccVideoSJpegCodec::encodeText(KviDataBuffer * textSignal, KviDataBuffer * stream) +{ + static unsigned const char *irct_magic_init = (unsigned const char*) "\0\0"; + static unsigned const char *irct_magic_end = (unsigned const char*) "\0\0"; + + qDebug("encodeText %s %d",textSignal->data(), textSignal->size()); + if(textSignal->size() < 1) return; + stream->append(irct_magic_init,8); + stream->append((const unsigned char*)textSignal->data(),textSignal->size()); + stream->append(irct_magic_end,9); + textSignal->clear(); + return; +} + +void DccVideoSJpegCodec::decode(KviDataBuffer * stream,KviDataBuffer * videoSignal,KviDataBuffer * textSignal) +{ + static unsigned const char jpg_magic_init[4] = { 0xFF, 0xD8, 0xFF, 0xE0}; //SOI + APP0 + static unsigned const char jpg_magic_end[2] = { 0xFF, 0xD9}; //EOI + + static unsigned const char *irct_magic_init = (unsigned const char*) "\0\0"; + static unsigned const char *irct_magic_end = (unsigned const char*) "\0\0"; + + if(stream->size() < 1)return; + + + int txtStart = stream->find(irct_magic_init, 8); + int txtEnd = stream->find(irct_magic_end, 9); + + int jpgStart = stream->find(jpg_magic_init, 4); + + if(txtStart!=-1 && txtEnd !=-1 && txtStartremove(txtStart+8); + int len = txtEnd - txtStart -8; //-8 irct_magic_init + if(len>0) + { + textSignal->append(stream->data(), len); + char*txt=(char*)malloc(len+1); + memcpy(txt,stream->data(), len); + txt[len]='\0'; + qDebug("a recv |%s| %d",txt,len); + } + stream->remove(len+9); + } + + if(stream->size() < 1)return; + + jpgStart = stream->find(jpg_magic_init, 4); + int jpgEnd = stream->find(jpg_magic_end, 2); + + if(jpgStart != -1 && jpgEnd != -1) + { +// qDebug("jpgStart %d jpgEnd %d",jpgStart,jpgEnd); + QImage img; + //remove junk before jpeg start + if(jpgStart > 0) + stream->remove(jpgStart); + + int len = jpgEnd - jpgStart + 1; + + img.loadFromData(stream->data(), stream->size()); + if(!img.isNull()) + { + videoSignal->clear(); + videoSignal->append(img.bits(),img.numBytes()); + } + stream->remove(len); + } + + txtStart = stream->find(irct_magic_init, 8); + txtEnd = stream->find(irct_magic_end, 9); + + if(txtStart!=-1 && txtEnd !=-1) + { + qDebug("b txtStart %d txtEnd %d",txtStart,txtEnd); + stream->remove(txtStart+8); + int len = txtEnd - txtStart -8; //-8 irct_magic_init + if(len>0) + { + textSignal->append(stream->data(), len); + char*txt=(char*)malloc(len+1); + memcpy(txt,stream->data(), len); + txt[len]='\0'; + qDebug("b recv |%s| %d",txt,len); + } + stream->remove(len+9); + } +} + +int DccVideoSJpegCodec::encodedFrameSize() +{ + return 0; +} + +int DccVideoSJpegCodec::decodedFrameSize() +{ + return 0; +} + + +#ifndef COMPILE_DISABLE_OGG_THEORA +DccVideoTheoraCodec::DccVideoTheoraCodec() +: DccVideoCodec() +{ + m_szName = "theora"; + m_pEncoder = 0; + m_pDecoder = 0; +} + +DccVideoTheoraCodec::~DccVideoTheoraCodec() +{ + if(m_pEncoder) + delete m_pEncoder; + m_pEncoder=0; + + if(m_pDecoder) + delete m_pDecoder; + m_pDecoder=0; +} + +void DccVideoTheoraCodec::encodeVideo(KviDataBuffer * videoSignal,KviDataBuffer * stream) +{ + if(videoSignal->size() < 1) return; + + if(!m_pEncoder) + m_pEncoder = new KviOggTheoraEncoder(stream); + + m_pEncoder->addVideoFrame((QRgb *) videoSignal->data(),videoSignal->size()); + videoSignal->clear(); +} + +void DccVideoTheoraCodec::encodeText(KviDataBuffer * textSignal, KviDataBuffer * stream) +{ + if(textSignal->size() < 1) return; + + if(!m_pEncoder) + m_pEncoder = new KviOggTheoraEncoder(stream); + + m_pEncoder->addTextFrame(textSignal->data(),textSignal->size()); + textSignal->clear(); +} + +void DccVideoTheoraCodec::decode(KviDataBuffer * stream,KviDataBuffer * videoSignal,KviDataBuffer * textSignal) +{ + if(stream->size() < 1)return; + + if(!m_pDecoder) + m_pDecoder = new KviOggTheoraDecoder(videoSignal, textSignal); + + m_pDecoder->addData(stream); +} + +int DccVideoTheoraCodec::encodedFrameSize() +{ + return 0; +} + +int DccVideoTheoraCodec::decodedFrameSize() +{ + return 0; +} +#endif // COMPILE_DISABLE_OGG_THEORA diff --git a/src/modules/dcc/DccVoiceCodec.h b/src/modules/dcc/DccVoiceCodec.h new file mode 100644 index 000000000..b8438c328 --- /dev/null +++ b/src/modules/dcc/DccVoiceCodec.h @@ -0,0 +1,108 @@ +#ifndef _CODEC_H_ +#define _CODEC_H_ +//============================================================================= +// +// File : DccVoiceCodec.h +// Creation date : Sun Aug 26 04:19:34 2001 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviCString.h" +#include "KviDataBuffer.h" + +#ifndef COMPILE_DISABLE_OGG_THEORA + #include "KviOggTheoraDecoder.h" + #include "KviOggTheoraEncoder.h" +#endif + +class DccVoiceCodec +{ +public: + DccVoiceCodec(); + virtual ~DccVoiceCodec(); +protected: + KviCString m_szName; +public: + const char * name(); + virtual void encode(KviDataBuffer * signal,KviDataBuffer * stream); + virtual void decode(KviDataBuffer * stream,KviDataBuffer * signal); + virtual int encodedFrameSize(); + virtual int decodedFrameSize(); +}; + +class DccVoiceNullCodec : public DccVoiceCodec +{ +public: + DccVoiceNullCodec(); + virtual ~DccVoiceNullCodec(); +public: + virtual void encode(KviDataBuffer * signal,KviDataBuffer * stream); + virtual void decode(KviDataBuffer * stream,KviDataBuffer * signal); + virtual int encodedFrameSize(); + virtual int decodedFrameSize(); +}; + +class DccVideoCodec +{ +public: + DccVideoCodec(); + virtual ~DccVideoCodec(); +protected: + KviCString m_szName; +public: + const char * name(); + virtual void encodeVideo(KviDataBuffer * videoSignal, KviDataBuffer * stream); + virtual void encodeText(KviDataBuffer * textSignal, KviDataBuffer * stream); + virtual void decode(KviDataBuffer * stream,KviDataBuffer * videoSignal,KviDataBuffer * textSignal); + virtual int encodedFrameSize(); + virtual int decodedFrameSize(); +}; + +class DccVideoSJpegCodec : public DccVideoCodec +{ +public: + DccVideoSJpegCodec(); + virtual ~DccVideoSJpegCodec(); +public: + virtual void encodeVideo(KviDataBuffer * videoSignal, KviDataBuffer * stream); + virtual void encodeText(KviDataBuffer * textSignal, KviDataBuffer * stream); + virtual void decode(KviDataBuffer * stream,KviDataBuffer * videoSignal,KviDataBuffer * textSignal); + virtual int encodedFrameSize(); + virtual int decodedFrameSize(); +}; + +#ifndef COMPILE_DISABLE_OGG_THEORA +class DccVideoTheoraCodec : public DccVideoCodec +{ +public: + DccVideoTheoraCodec(); + virtual ~DccVideoTheoraCodec(); +public: + virtual void encodeVideo(KviDataBuffer * videoSignal, KviDataBuffer * stream); + virtual void encodeText(KviDataBuffer * textSignal, KviDataBuffer * stream); + virtual void decode(KviDataBuffer * stream,KviDataBuffer * videoSignal,KviDataBuffer * textSignal); + virtual int encodedFrameSize(); + virtual int decodedFrameSize(); +private: + KviOggTheoraEncoder * m_pEncoder; + KviOggTheoraDecoder * m_pDecoder; +}; +#endif // COMPILE_DISABLE_OGG_THEORA +#endif //_CODEC_H_ diff --git a/src/modules/dcc/DccVoiceGsmCodec.cpp b/src/modules/dcc/DccVoiceGsmCodec.cpp new file mode 100644 index 000000000..61961fd63 --- /dev/null +++ b/src/modules/dcc/DccVoiceGsmCodec.cpp @@ -0,0 +1,148 @@ +//============================================================================= +// +// File : DccVoiceGsmCodec.cpp +// Creation date : Wed Aug 22 19:12:55 2001 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#define _GSMCODEC_CPP_ + +#include "DccVoiceGsmCodec.h" + +#ifdef COMPILE_USE_GSM + #include + + #define GSM_PACKED_FRAME_SIZE_IN_BYTES 33 + #define GSM_UNPACKED_FRAME_SIZE_IN_BYTES 320 + #define GSM_UNPACKED_FRAME_SIZE_IN_SHORTS 160 + + void * (*gsm_session_create)() = 0; + void (*gsm_session_destroy)(void *) = 0; + void (*gsm_session_encode)(void *,short *,unsigned char *) = 0; + int (*gsm_session_decode)(void *,unsigned char *,short *) = 0; + + void * g_pGSMCodecLibraryHandle = 0; + + bool kvi_gsm_codec_init() + { + if(g_pGSMCodecLibraryHandle)return true; // Already initialized + + g_pGSMCodecLibraryHandle = dlopen("libgsm.so",RTLD_NOW | RTLD_GLOBAL); + if(!g_pGSMCodecLibraryHandle)return false; // no way to open it + + gsm_session_create = (void * (*)()) dlsym(g_pGSMCodecLibraryHandle,"gsm_create"); + gsm_session_destroy = (void (*)(void *)) dlsym(g_pGSMCodecLibraryHandle,"gsm_destroy"); + gsm_session_encode = (void (*)(void *,short *,unsigned char *)) dlsym(g_pGSMCodecLibraryHandle,"gsm_encode"); + gsm_session_decode = (int (*)(void *,unsigned char *,short *)) dlsym(g_pGSMCodecLibraryHandle,"gsm_decode"); + + if(! (gsm_session_create && gsm_session_destroy && gsm_session_encode && gsm_session_decode)) + { + dlclose(g_pGSMCodecLibraryHandle); + g_pGSMCodecLibraryHandle = 0; + return false; + } + return true; + } + + void kvi_gsm_codec_done() + { + if(g_pGSMCodecLibraryHandle) + { + dlclose(g_pGSMCodecLibraryHandle); + g_pGSMCodecLibraryHandle = 0; + } + } + + + DccVoiceGsmCodec::DccVoiceGsmCodec() + : DccVoiceCodec() + { + m_pEncodeState = gsm_session_create(); + m_pDecodeState = gsm_session_create(); + m_szName = "gsm (compression 33:320)"; + } + + DccVoiceGsmCodec::~DccVoiceGsmCodec() + { + gsm_session_destroy(m_pEncodeState); + gsm_session_destroy(m_pDecodeState); + } + + void DccVoiceGsmCodec::encode(KviDataBuffer * signal,KviDataBuffer * stream) + { + if(signal->size() < GSM_UNPACKED_FRAME_SIZE_IN_BYTES)return; // nothing to encode + + unsigned char * ptr = signal->data(); + + int uFrames = signal->size() / GSM_UNPACKED_FRAME_SIZE_IN_BYTES; + int uTotalDataCompressed = uFrames * GSM_UNPACKED_FRAME_SIZE_IN_BYTES; + int uFrameOffset = stream->size(); + unsigned char * endPtr = ptr + uTotalDataCompressed; + + stream->addSize(GSM_PACKED_FRAME_SIZE_IN_BYTES * uFrames); + + while(ptr != endPtr) + { + gsm_session_encode(m_pEncodeState,(short *)ptr,stream->data() + uFrameOffset); + ptr += GSM_UNPACKED_FRAME_SIZE_IN_BYTES; + uFrameOffset += GSM_PACKED_FRAME_SIZE_IN_BYTES; + } + signal->remove(uTotalDataCompressed); + } + + void DccVoiceGsmCodec::decode(KviDataBuffer * stream,KviDataBuffer * signal) + { + if(stream->size() < GSM_PACKED_FRAME_SIZE_IN_BYTES)return; // nothing to decode + + unsigned char * ptr = stream->data(); + + // Gsm codec + int uFrames = stream->size() / GSM_PACKED_FRAME_SIZE_IN_BYTES; + int uTotalDataDecompressed = uFrames * GSM_PACKED_FRAME_SIZE_IN_BYTES; + int uSignalOffset = signal->size(); + unsigned char * endPtr = ptr + (uTotalDataDecompressed); + + signal->addSize(GSM_UNPACKED_FRAME_SIZE_IN_BYTES * uFrames); + + while(ptr != endPtr) + { + // We don't check the return value here + // Well..it is either an unrecoverable internal error + // or a broken frame... + // but if we receive broken frames over DCC...well....better + // check the hardware...or the remote codec as well... + gsm_session_decode(m_pDecodeState,ptr,(short *)(signal->data() + uSignalOffset)); + ptr += GSM_PACKED_FRAME_SIZE_IN_BYTES; + uSignalOffset += GSM_UNPACKED_FRAME_SIZE_IN_BYTES; + } + stream->remove(uTotalDataDecompressed); + } + + int DccVoiceGsmCodec::encodedFrameSize() + { + return GSM_PACKED_FRAME_SIZE_IN_BYTES; + } + + int DccVoiceGsmCodec::decodedFrameSize() + { + return GSM_UNPACKED_FRAME_SIZE_IN_BYTES; + } + +#endif // COMPILE_USE_GSM diff --git a/src/modules/dcc/DccVoiceGsmCodec.h b/src/modules/dcc/DccVoiceGsmCodec.h new file mode 100644 index 000000000..cd820e7d6 --- /dev/null +++ b/src/modules/dcc/DccVoiceGsmCodec.h @@ -0,0 +1,56 @@ +#ifndef _GSMCODEC_H_ +#define _GSMCODEC_H_ +//============================================================================= +// +// File : DccVoiceGsmCodec.h +// Creation date : Wed Aug 22 19:12:54 2001 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" + + +#ifdef COMPILE_USE_GSM + + #include "DccVoiceCodec.h" + + #ifndef _GSMCODEC_CPP_ + extern bool kvi_gsm_codec_init(); + extern void kvi_gsm_codec_done(); + #endif //_GSMCODEC_CPP_ + + class DccVoiceGsmCodec : public DccVoiceCodec + { + public: + DccVoiceGsmCodec(); + virtual ~DccVoiceGsmCodec(); + private: + void * m_pEncodeState; + void * m_pDecodeState; + public: + virtual void encode(KviDataBuffer * signal,KviDataBuffer * stream); + virtual void decode(KviDataBuffer * stream,KviDataBuffer * signal); + virtual int encodedFrameSize(); + virtual int decodedFrameSize(); + }; + +#endif //COMPILE_USE_GSM + +#endif //_GSMCODEC_H_ diff --git a/src/modules/dcc/DccVoiceWindow.cpp b/src/modules/dcc/DccVoiceWindow.cpp new file mode 100644 index 000000000..f1ede8af7 --- /dev/null +++ b/src/modules/dcc/DccVoiceWindow.cpp @@ -0,0 +1,1033 @@ +//============================================================================= +// +// File : DccVoiceWindow.cpp +// Creation date : Thu Aug 23 04:08:09 2001 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "DccVoiceWindow.h" +#include "DccMarshal.h" +#include "DccBroker.h" +#include "DccVoiceAdpcmCodec.h" +#include "DccVoiceGsmCodec.h" + +#include "kvi_settings.h" +#include "KviIconManager.h" +#include "KviIrcView.h" +#include "KviLocale.h" +#include "kvi_out.h" +#include "KviNetUtils.h" +#include "KviOptions.h" +#include "KviConsoleWindow.h" +#include "KviMemory.h" +#include "kvi_socket.h" +#include "KviIrcConnection.h" +#include "KviTalVBox.h" + +#include +#include +#include + +#if !defined(COMPILE_ON_WINDOWS) && !defined(COMPILE_ON_MINGW) + #include + #include + #include + #include + #include + //#include "KviError.h" + #include // for open() + #include // for ioctl() +#endif + +extern DccBroker * g_pDccBroker; + +//Check for the *SS Api....we don't want to fail here... + +#ifndef COMPILE_DISABLE_DCC_VOICE + #ifdef HAVE_LINUX_SOUNDCARD_H + #include + #else + #ifdef HAVE_SYS_SOUNDCARD_H + #include + #else + #ifdef HAVE_SOUNDCARD_H + #include + #else + //CAN NOT COMPILE :( + #define COMPILE_DISABLE_DCC_VOICE + #if !defined(COMPILE_ON_WINDOWS) && !defined(COMPILE_ON_MINGW) + #warning "Cannot find the soundcard.h header; you will NOT be able to use DCC Voice" + #endif + #endif + #endif + #endif +#endif + + +//#define KVI_AUDIO_DEVICE "/dev/dsp" +// 32 fragments, 512 bytes +#define KVI_SNDCTL_FRAG_SIZE 0x00B00009 +#define KVI_FRAGMENT_SIZE_IN_BYTES 512 +#define KVI_FORMAT AFMT_S16_LE +#define KVI_NUM_CHANNELS 1 + + +bool kvi_dcc_voice_is_valid_codec(const char * codecName) +{ +#ifdef COMPILE_USE_GSM + if(kvi_strEqualCI("gsm",codecName)) + { + return kvi_gsm_codec_init(); + } +#endif + if(kvi_strEqualCI("adpcm",codecName))return true; + if(kvi_strEqualCI("null",codecName))return true; + return false; +} + +static DccVoiceCodec * kvi_dcc_voice_get_codec(const char * codecName) +{ +#ifdef COMPILE_USE_GSM + if(kvi_strEqualCI("gsm",codecName)) + { + if(kvi_gsm_codec_init())return new DccVoiceGsmCodec(); + } +#endif + if(kvi_strEqualCI("adpcm",codecName))return new DccVoiceAdpcmCodec(); + if(kvi_strEqualCI("null",codecName))return new DccVoiceNullCodec(); + return new DccVoiceAdpcmCodec(); +} + + +DccVoiceThread::DccVoiceThread(KviWindow * wnd,kvi_socket_t fd,KviDccVoiceThreadOptions * opt) +: DccThread(wnd,fd) +{ +#ifndef COMPILE_DISABLE_DCC_VOICE + m_pOpt = opt; + m_bPlaying = false; + m_bRecording = false; + m_bSoundcardChecked = false; + m_soundFd = -1; + m_soundFdMode = 0; + m_pInfoMutex = new KviMutex(); + m_bRecordingRequestPending = false; +#endif +} + +DccVoiceThread::~DccVoiceThread() +{ +#ifndef COMPILE_DISABLE_DCC_VOICE + delete m_pOpt->pCodec; + delete m_pOpt; + delete m_pInfoMutex; +#endif +} + +bool DccVoiceThread::checkSoundcard() +{ +#ifdef COMPILE_DISABLE_DCC_VOICE + return false; +#else + bool bOpened = false; + if(m_soundFd == -1) + { + if(!openSoundcard(O_RDONLY))return false; + bOpened = true; + } + + int caps; + + m_bSoundcardChecked = true; + + if(ioctl(m_soundFd,SNDCTL_DSP_GETCAPS,&caps) < 0) + { + postMessageEvent(__tr2qs_ctx("WARNING: failed to check the soundcard duplex capabilities: if this is a half-duplex soundcard, use the DCC VOICE option to force half-duplex algorithm","dcc").toUtf8().data()); + if(bOpened)closeSoundcard(); + return false; + } + + if(!(caps & DSP_CAP_DUPLEX)) + { + m_pOpt->bForceHalfDuplex = true; // the device is half duplex...use it in that way + postMessageEvent(__tr2qs_ctx("Half duplex soundcard detected, you will not be able to talk and listen at the same time","dcc").toUtf8().data()); + } + + if(bOpened)closeSoundcard(); + + return true; +#endif +} + + +bool DccVoiceThread::openSoundcard(int mode) +{ +#ifdef COMPILE_DISABLE_DCC_VOICE + return false; +#else + int speed = m_pOpt->iSampleRate; + static int chans=KVI_NUM_CHANNELS; + static int fmt=KVI_FORMAT; + static int frag = KVI_SNDCTL_FRAG_SIZE; + + + if(m_soundFd != -1) + { + if(m_soundFdMode == mode)return true; // already open + closeSoundcard(); + } + + m_soundFd = ::open(m_pOpt->szSoundDevice.ptr(),mode | O_NONBLOCK); + if(m_soundFd < 0)return false; + + if(!m_pOpt->bForceHalfDuplex) + { + if(ioctl(m_soundFd,SNDCTL_DSP_SETDUPLEX,0) < 0)goto exit_false; + } + + if(ioctl(m_soundFd,SNDCTL_DSP_SETFRAGMENT,&frag)<0)goto exit_false; + if(ioctl(m_soundFd,SNDCTL_DSP_SETFMT,&fmt)<0)goto exit_false; + if(ioctl(m_soundFd,SNDCTL_DSP_CHANNELS,&chans)<0)goto exit_false; + if(ioctl(m_soundFd,SNDCTL_DSP_SPEED,&speed)<0)goto exit_false; + if(speed != m_pOpt->iSampleRate) + { + KviCString tmp(KviCString::Format,__tr2qs_ctx("WARNING: failed to set the requested sample rate (%d): the device used closest match (%d)","dcc").toUtf8().data(), + m_pOpt->iSampleRate,speed); + postMessageEvent(tmp.ptr()); + } + + // TODO: #warning "We could also support blocking operations mode" + + m_soundFdMode = mode; + + + return true; + +exit_false: + closeSoundcard(); + return false; +#endif +} + +bool DccVoiceThread::openSoundcardForWriting() +{ +#ifndef COMPILE_DISABLE_DCC_VOICE + return openSoundcardWithDuplexOption(O_WRONLY,O_RDONLY); +#else + return false; +#endif +} + +bool DccVoiceThread::openSoundcardForReading() +{ +#ifndef COMPILE_DISABLE_DCC_VOICE + return openSoundcardWithDuplexOption(O_RDONLY,O_WRONLY); +#else + return false; +#endif +} + +bool DccVoiceThread::openSoundcardWithDuplexOption(int openMode,int failMode) +{ +#ifndef COMPILE_DISABLE_DCC_VOICE + if(m_soundFd == -1) + { + // soundcard not open yet...open for write (at least) + if(m_pOpt->bForceHalfDuplex) + { + // Forcing half duplex... (user option or the card does not support full duplex mode) + if(!openSoundcard(openMode))return false; + } else { + // Try read/write open + if(!openSoundcard(O_RDWR)) + { + // half-duplex sound card ? + if(!m_bSoundcardChecked) + { + // We haven't checked the full-duplex support yet... + // Try to open in RDONLY o WRONLY mode + if(!openSoundcard(openMode))return false; + if(!checkSoundcard()) + { + postMessageEvent(__tr2qs_ctx("Ops...failed to test the soundcard capabilities...expect problems...","dcc").toUtf8().data()); + } + } // else the test has been done and it is a full duplex card that is just busy + } + } + } else { + // Hmmm...already open + // If it is open in O_RDWR or O_WRONLY mode...it is ok for us + // but if it is open in O_RDONLY mode...we can do nothing...just wait + return (m_soundFdMode != failMode); + } + + return true; +#else + return false; +#endif +} + +void DccVoiceThread::closeSoundcard() +{ +#ifndef COMPILE_DISABLE_DCC_VOICE + if(m_soundFd != -1) + { + ::close(m_soundFd); + m_soundFd = -1; + m_soundFdMode = 0; + } +#endif +} + +bool DccVoiceThread::readWriteStep() +{ +#ifndef COMPILE_DISABLE_DCC_VOICE + // Socket management + bool bCanRead; + bool bCanWrite; + + if(kvi_select(m_fd,&bCanRead,&bCanWrite)) + { + if(bCanRead) + { + unsigned int actualSize = m_inFrameBuffer.size(); + m_inFrameBuffer.resize(actualSize + 1024); + int readLen = kvi_socket_recv(m_fd,(void *)(m_inFrameBuffer.data() + actualSize),1024); + if(readLen > 0) + { + if(readLen < 1024)m_inFrameBuffer.resize(actualSize + readLen); + m_pOpt->pCodec->decode(&m_inFrameBuffer,&m_inSignalBuffer); +//#warning "A maximum length for the signal buffer is actually needed!!!" + } else { + if(!handleInvalidSocketRead(readLen))return false; + m_inFrameBuffer.resize(actualSize); + } + }// else { + // m_uSleepTime += 100; + //} + + if(bCanWrite) + { + // Have somethihg to write ? + if(m_outFrameBuffer.size() > 0) + { + int written = kvi_socket_send(m_fd,m_outFrameBuffer.data(),m_outFrameBuffer.size()); + if(written > 0) + { + m_outFrameBuffer.remove(written); + } else { + if(!handleInvalidSocketRead(written))return false; + } + }// else { + // m_uSleepTime += 100; + // } + }// else { + // m_uSleepTime += 100; +// } +//#warning "Usleep here ?" + }// else { +// if(!(m_bPlaying || m_bRecording)) +// { +// // Really NOTHING is happening...sleep a bit more +// m_uSleepTime += 800; +// } else { +// m_uSleepTime += 100; +// } +// } + +#endif // !COMPILE_DISABLE_DCC_VOICE + return true; +} + +bool DccVoiceThread::soundStep() +{ +#ifndef COMPILE_DISABLE_DCC_VOICE + // Are we playing ? + if(m_bPlaying) + { + // Do we have something to write ? + audio_buf_info info; + if(m_inSignalBuffer.size() > 0) + { + // Get the number of fragments that can be written to the soundcard without blocking + + if(ioctl(m_soundFd,SNDCTL_DSP_GETOSPACE,&info) < 0) + { + qDebug("get o space failed"); + info.bytes = KVI_FRAGMENT_SIZE_IN_BYTES; // dummy... if this is not correct...well...we will block for 1024/16000 of a sec + info.fragments = 1; + info.fragsize = KVI_FRAGMENT_SIZE_IN_BYTES; + } + if(info.fragments > 0) + { + int toWrite = info.fragments * info.fragsize; + //qDebug("Can write %d bytes",toWrite); + if(m_inSignalBuffer.size() < toWrite)toWrite = m_inSignalBuffer.size(); + int written = write(m_soundFd,m_inSignalBuffer.data(),toWrite); + if(written > 0)m_inSignalBuffer.remove(written); + else { +//#warning "Do something for -1 here ?" +//#warning "Usleep ?" + } + } //else { + // No stuff can be written...we are running too fast ? + // m_uSleepTime += 100; // sleep for a while + //} + } else { + // hmmmm....playing, but nothing to write, possible underrun or EOF + // a nice idea would be to use SNDCTL_DSP_GETODELAY here... + // but it appears to be broken on some audio devices + if(ioctl(m_soundFd,SNDCTL_DSP_GETOSPACE,&info) < 0)info.fragstotal = info.fragments; // dummy...but what should we do ? + if(info.fragstotal == info.fragments) + { + // underrun or EOF: close the device + stopPlaying(); + } + } + } else { + // do we have anything to play ? + if(m_inSignalBuffer.size() > 0) + { + if(m_inSignalBuffer.size() >= m_pOpt->iPreBufferSize) + { + // yep...stuff to play... open the soundcard, if possible + startPlaying(); + + m_iLastSignalBufferSize = m_inSignalBuffer.size(); + } else { + // have stuff to play, but it's not enough to fill the pre-buffer + // + struct timeval tv; + gettimeofday(&tv,0); + + long int sigBufferTime = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); + + if(m_inSignalBuffer.size() == m_iLastSignalBufferSize) + { + // the same signal buffer size... check the time + // m_pOpt->iPreBufferSize / 16 gives us the preBufferTime in msecs + // we calc the remaining preBufferTime by subtracting the + // size of buffer already filled and we also add 50 milliseconds... smart heuristic + int preBufferTime = ((m_pOpt->iPreBufferSize - m_iLastSignalBufferSize) / 16) + 50; + // if the buffer size hasn't changed since preBufferTime + // it's time to start playing anyway, since there is + // either a network stall or it was just a really short data stream + if((sigBufferTime - m_iLastSignalBufferTime) > preBufferTime) + { + startPlaying(); + if(m_bPlaying)m_iLastSignalBufferSize = 0; + } + } else { + // signal buffer size differs...we have received new packets + // and still pre-buffering + m_iLastSignalBufferSize = m_inSignalBuffer.size(); + m_iLastSignalBufferTime = sigBufferTime; + } + } + + } + } + + // Are we recording ? + if(m_bRecording) + { + fd_set rs; + FD_ZERO(&rs); + FD_SET(m_soundFd,&rs); + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 10; + int ret = select(m_soundFd + 1,&rs,0,0,&tv); + if(ret > 0) + { + // This is rather easy... + audio_buf_info info; + if(ioctl(m_soundFd,SNDCTL_DSP_GETISPACE,&info) < 0) + { + qDebug("Ispace failed"); + info.fragments = 0; // dummy... + info.bytes = 0; + } + + //qDebug("INFO: fragments: %d, fragstotal: %d, fragsize: %d, bytes: %d",info.fragments,info.fragstotal,info.fragsize,info.bytes); + + if(info.fragments == 0 && info.bytes == 0) + { + // force a dummy read: the device needs to be triggered + info.fragments = 1; + } + + if(info.fragments > 0) + { + int oldSize = m_outSignalBuffer.size(); + int available = info.fragments * info.fragsize; + m_outSignalBuffer.addSize(available); + int readed = read(m_soundFd,m_outSignalBuffer.data() + oldSize,available); + + if(readed < available) + { + // huh ? ...error ? + if(readed >= 0)m_outSignalBuffer.resize(oldSize + readed); + else { + if((errno == EINTR) || (errno == EAGAIN)) + { + m_outSignalBuffer.resize(oldSize); + } else { +//#warning "Critical error...do something reasonable!" + m_outSignalBuffer.resize(oldSize); + } + } + } +/* + qDebug("Signal buffer:"); + for(int i=0;i<200;i+=2) + { + if(i >= m_outSignalBuffer.size())break; + printf("%04x ",*(((unsigned short *)(m_outSignalBuffer.data() + i)))); + if((i % 6) == 0)printf("\n"); + } + qDebug("END\n"); +*/ + m_pOpt->pCodec->encode(&m_outSignalBuffer,&m_outFrameBuffer); + } + }// else { + // Nothing to read + // m_uSleepTime += 100; + // } + } + +#endif // !COMPILE_DISABLE_DCC_VOICE + return true; +} + +void DccVoiceThread::startRecording() +{ +#ifndef COMPILE_DISABLE_DCC_VOICE + //qDebug("Start recording"); + if(m_bRecording)return; // already started + if(openSoundcardForReading()) + { +// qDebug("Posting event"); + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); + e->setData(new int(KVI_DCC_VOICE_THREAD_ACTION_START_RECORDING)); + postEvent(parent(),e); + + m_bRecording = true; + m_bRecordingRequestPending = false; + } else { + m_bRecordingRequestPending = true; + } +#endif +} + +void DccVoiceThread::stopRecording() +{ +#ifndef COMPILE_DISABLE_DCC_VOICE + //qDebug("Stop recording"); + m_bRecordingRequestPending = false; + if(!m_bRecording)return; // already stopped + + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); + e->setData(new int(KVI_DCC_VOICE_THREAD_ACTION_STOP_RECORDING)); + postEvent(parent(),e); + + m_bRecording = false; + if(!m_bPlaying)closeSoundcard(); +#endif +} + +void DccVoiceThread::startPlaying() +{ +#ifndef COMPILE_DISABLE_DCC_VOICE + //qDebug("Start playing"); + if(m_bPlaying)return; + + if(openSoundcardForWriting()) + { + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); + e->setData(new int(KVI_DCC_VOICE_THREAD_ACTION_START_PLAYING)); + postEvent(parent(),e); + m_bPlaying = true; + } +#endif +} + +void DccVoiceThread::stopPlaying() +{ +#ifndef COMPILE_DISABLE_DCC_VOICE + //qDebug("Stop playing"); + if(!m_bPlaying)return; + + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); + e->setData(new int(KVI_DCC_VOICE_THREAD_ACTION_STOP_PLAYING)); + postEvent(parent(),e); + + m_bPlaying = false; + if(!m_bRecording)closeSoundcard(); +#endif +} + +void DccVoiceThread::run() +{ +#ifndef COMPILE_DISABLE_DCC_VOICE + for(;;) + { +// m_uSleepTime = 0; + + // Dequeue events + while(KviThreadEvent * e = dequeueEvent()) + { + if(e->id() == KVI_THREAD_EVENT_TERMINATE) + { + delete e; + goto exit_dcc; + } else if(e->id() == KVI_DCC_THREAD_EVENT_ACTION) + { + int * act = ((KviThreadDataEvent *)e)->getData(); + if(*act)startRecording(); + else stopRecording(); + delete act; + delete e; + } else { + // Other events are senseless to us + delete e; + } + } + + if(!readWriteStep())goto exit_dcc; + if(!soundStep())goto exit_dcc; + + m_pInfoMutex->lock(); + m_iInputBufferSize = m_inSignalBuffer.size(); + m_iOutputBufferSize = (m_outFrameBuffer.size() / m_pOpt->pCodec->encodedFrameSize()) * m_pOpt->pCodec->decodedFrameSize(); + m_pInfoMutex->unlock(); + + // Actually the maximum that we can sleep here is + // around 500 usecs... = 0.0005 sec -> 8 bytes at 8 KHz + + // if(m_uSleepTime)usleep(m_uSleepTime); + + // Start recording if the request was not fulfilled yet + if(m_bRecordingRequestPending)startRecording(); + } + + +exit_dcc: + +#endif //! COMPILE_DISABLE_DCC_VOICE + closeSoundcard(); + kvi_socket_close(m_fd); + m_fd = KVI_INVALID_SOCKET; +} + + +DccVoiceWindow::DccVoiceWindow(KviMainWindow *pFrm,DccDescriptor * dcc,const char * name) +: DccWindow(KVI_WINDOW_TYPE_DCCVOICE,pFrm,name,dcc) +{ + m_pDescriptor = dcc; + m_pSlaveThread = 0; + + m_pSplitter = new KviTalSplitter(Qt::Horizontal,this); + m_pSplitter->setObjectName("dcc_window_splitter"); + m_pIrcView = new KviIrcView(m_pSplitter,pFrm,this); + + m_pHBox = new KviTalHBox(this); + + KviTalVBox * vbox = new KviTalVBox(m_pHBox); + + m_pInputLabel = new QLabel(__tr2qs_ctx("Input buffer","dcc"),vbox); + m_pInputLabel->setFrameStyle(QFrame::Sunken | QFrame::Panel); + m_pOutputLabel = new QLabel(__tr2qs_ctx("Output buffer","dcc"),vbox); + m_pOutputLabel->setFrameStyle(QFrame::Sunken | QFrame::Panel); + vbox->setSpacing(1); + + KviTalVBox * vbox2 = new KviTalVBox(m_pHBox); + + m_pRecordingLabel = new QLabel(vbox2); + m_pRecordingLabel->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_RECORD))); + m_pRecordingLabel->setEnabled(false); + m_pRecordingLabel->setFrameStyle(QFrame::Raised | QFrame::Panel); + + m_pPlayingLabel = new QLabel(vbox2); + m_pPlayingLabel->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_PLAY))); + m_pPlayingLabel->setEnabled(false); + m_pPlayingLabel->setFrameStyle(QFrame::Raised | QFrame::Panel); + + vbox2->setSpacing(1); + + //#warning "The volume slider should be enabled only when receiving data" + //m_pVolumeSlider = new QSlider(-100, 0, 10, 0, Qt::Vertical, m_pHBox, "dcc_voice_volume_slider"); + m_pVolumeSlider = new QSlider(Qt::Vertical,m_pHBox); + m_pVolumeSlider->setObjectName("dcc_voice_volume_slider"); + m_pVolumeSlider->setMinimum(-100); + m_pVolumeSlider->setMaximum(0); + m_pVolumeSlider->setPageStep(10); + m_pVolumeSlider->setValue(0); + + m_pVolumeSlider->setValue(getMixerVolume()); + /* Update the tooltip */ + setMixerVolume(m_pVolumeSlider->value()); + m_pVolumeSlider->setMaximumWidth(16); + m_pVolumeSlider->setMaximumHeight(2*m_pPlayingLabel->height()); + connect(m_pVolumeSlider, SIGNAL(valueChanged(int)), this, SLOT(setMixerVolume(int))); + + m_pTalkButton = new QToolButton(m_pHBox); + m_pTalkButton->setEnabled(false); + m_pTalkButton->setCheckable(true); + QIcon iset; + iset.addPixmap(*(g_pIconManager->getBigIcon(KVI_BIGICON_DISCONNECTED)),QIcon::Normal,QIcon::Off); + iset.addPixmap(*(g_pIconManager->getBigIcon(KVI_BIGICON_CONNECTED)),QIcon::Normal,QIcon::On); + m_pTalkButton->setIcon(iset); + m_pTalkButton->setIconSize(QSize(32,32)); + connect(m_pTalkButton,SIGNAL(toggled(bool)),this,SLOT(startOrStopTalking(bool))); + + m_pHBox->setStretchFactor(vbox,1); + m_pHBox->setMargin(2); + m_pHBox->setSpacing(1); + + //setFocusHandler(m_pIrcView,this); + + m_pMarshal = new DccMarshal(this); + connect(m_pMarshal,SIGNAL(error(int)),this,SLOT(handleMarshalError(int))); + connect(m_pMarshal,SIGNAL(connected()),this,SLOT(connected())); + connect(m_pMarshal,SIGNAL(inProgress()),this,SLOT(connectionInProgress())); + + m_pUpdateTimer = new QTimer(); + + startConnection(); +} + +DccVoiceWindow::~DccVoiceWindow() +{ + g_pDccBroker->unregisterDccWindow(this); + if(m_pSlaveThread) + { + m_pSlaveThread->terminate(); + delete m_pSlaveThread; + m_pSlaveThread = 0; + } + + KviThreadManager::killPendingEvents(this); + + delete m_pUpdateTimer; +// delete m_pDescriptor; +// delete m_pMarshal; +} + + +void DccVoiceWindow::startConnection() +{ + if(!(m_pDescriptor->bActive)) + { + // PASSIVE CONNECTION + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Attempting a passive DCC VOICE connection","dcc")); + KviError::Code eError = m_pMarshal->dccListen(m_pDescriptor->szListenIp,m_pDescriptor->szListenPort,m_pDescriptor->bDoTimeout); + if(eError != KviError::Success) + handleMarshalError(eError); + } else { + // ACTIVE CONNECTION + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Attempting an active DCC VOICE connection","dcc")); + KviError::Code eError = m_pMarshal->dccConnect(m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data(),m_pDescriptor->bDoTimeout); + if(eError != KviError::Success) + handleMarshalError(eError); + } +} + +void DccVoiceWindow::connectionInProgress() +{ + if(m_pDescriptor->bActive) + { + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Contacting host %Q on port %Q","dcc"),&(m_pDescriptor->szIp),&(m_pDescriptor->szPort)); + } else { + + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Listening on interface %Q port %Q","dcc"), + &(m_pMarshal->localIp()),&(m_pMarshal->localPort())); + + if(m_pDescriptor->bSendRequest) + { + QString ip = !m_pDescriptor->szFakeIp.isEmpty() ? m_pDescriptor->szFakeIp : m_pDescriptor->szListenIp; + KviCString port = !m_pDescriptor->szFakePort.isEmpty() ? m_pDescriptor->szFakePort : m_pMarshal->localPort(); +//#warning "OPTION FOR SENDING 127.0.0.1 and so on (not an unsigned nuumber)" + struct in_addr a; + if(KviNetUtils::stringIpToBinaryIp(ip,&a)) { + ip.setNum(htonl(a.s_addr)); + } + + m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC VOICE %s %Q %s %d%c", + m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(), + 0x01,m_pDescriptor->szCodec.ptr(), + &ip,port.ptr(),m_pDescriptor->iSampleRate,0x01); + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Sent DCC VOICE (%s) request to %Q, waiting for the remote client to connect...","dcc"), + m_pDescriptor->szCodec.ptr(),&(m_pDescriptor->szNick)); + } else output(KVI_OUT_DCCMSG,__tr2qs_ctx("DCC VOICE request not sent: awaiting manual connections","dcc")); + } +} + +const QString & DccVoiceWindow::target() +{ + // This may change on the fly... + m_szTarget.sprintf("%s@%s:%s", + m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data()); + return m_szTarget; +} + +void DccVoiceWindow::getBaseLogFileName(QString &buffer) +{ + buffer.sprintf("dccvoice_%s_%s_%s",m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szLocalFileName.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data()); +} + +void DccVoiceWindow::fillCaptionBuffers() +{ + KviCString tmp(KviCString::Format,"DCC Voice %s@%s:%s %s", + m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data(), + m_pDescriptor->szLocalFileName.toUtf8().data()); + + m_szPlainTextCaption = tmp; +} + +QPixmap * DccVoiceWindow::myIconPtr() +{ + return g_pIconManager->getSmallIcon(KVI_SMALLICON_DCCVOICE); +} + +bool DccVoiceWindow::event(QEvent *e) +{ + if(e->type() == KVI_THREAD_EVENT) + { + switch(((KviThreadEvent *)e)->id()) + { + case KVI_DCC_THREAD_EVENT_ERROR: + { + KviError::Code * pError = ((KviThreadDataEvent *)e)->getData(); + QString ssss = KviError::getDescription(*pError); + output(KVI_OUT_DCCERROR,__tr2qs_ctx("ERROR: %Q","dcc"),&(ssss)); + delete pError; + m_pUpdateTimer->stop(); + updateInfo(); + m_pTalkButton->setEnabled(false); + m_pRecordingLabel->setEnabled(false); + m_pPlayingLabel->setEnabled(false); + return true; + } + break; + case KVI_DCC_THREAD_EVENT_MESSAGE: + { + KviCString * str = ((KviThreadDataEvent *)e)->getData(); + outputNoFmt(KVI_OUT_DCCMSG,__tr_no_xgettext_ctx(str->ptr(),"dcc")); + delete str; + return true; + } + break; + case KVI_DCC_THREAD_EVENT_ACTION: + { + int * act = ((KviThreadDataEvent *)e)->getData(); + switch(*act) + { + case KVI_DCC_VOICE_THREAD_ACTION_START_RECORDING: + m_pRecordingLabel->setEnabled(true); + break; + case KVI_DCC_VOICE_THREAD_ACTION_STOP_RECORDING: + m_pRecordingLabel->setEnabled(false); + break; + case KVI_DCC_VOICE_THREAD_ACTION_START_PLAYING: + m_pPlayingLabel->setEnabled(true); + break; + case KVI_DCC_VOICE_THREAD_ACTION_STOP_PLAYING: + m_pPlayingLabel->setEnabled(false); + break; + } + delete act; + return true; + } + break; + default: + qDebug("Invalid event type %d received",((KviThreadEvent *)e)->id()); + break; + } + + } + + return KviWindow::event(e); +} + +void DccVoiceWindow::updateInfo() +{ + if(m_pSlaveThread) + { + m_pSlaveThread->m_pInfoMutex->lock(); + int iOSize = m_pSlaveThread->m_iOutputBufferSize; + int iISize = m_pSlaveThread->m_iInputBufferSize; + m_pSlaveThread->m_pInfoMutex->unlock(); + KviCString tmp(KviCString::Format,__tr_ctx("Input buffer: %d bytes","dcc"),iISize); + m_pInputLabel->setText(tmp.ptr()); + tmp.sprintf(__tr_ctx("Output buffer: %d bytes","dcc"),iOSize); + m_pOutputLabel->setText(tmp.ptr()); + } +} + +void DccVoiceWindow::resizeEvent(QResizeEvent *) +{ + int hght2 = m_pHBox->sizeHint().height(); + m_pHBox->setGeometry(0,0,width(),hght2); + m_pSplitter->setGeometry(0,hght2,width(),height() - hght2); +} + +QSize DccVoiceWindow::sizeHint() const +{ + int w = m_pIrcView->sizeHint().width(); + int w2 = m_pHBox->sizeHint().width(); + QSize ret(w > w2 ? w : w2, m_pIrcView->sizeHint().height() + m_pHBox->sizeHint().height()); + return ret; +} + +void DccVoiceWindow::handleMarshalError(KviError::Code eError) +{ + QString ssss = KviError::getDescription(eError); + output(KVI_OUT_DCCERROR,__tr2qs_ctx("DCC Failed: %Q","dcc"),&ssss); + m_pTalkButton->setEnabled(false); + m_pTalkButton->setChecked(false); + m_pRecordingLabel->setEnabled(false); + m_pPlayingLabel->setEnabled(false); +} + +void DccVoiceWindow::connected() +{ + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Connected to %Q:%Q","dcc"), + &(m_pMarshal->remoteIp()),&(m_pMarshal->remotePort())); + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Local end is %Q:%Q","dcc"), + &(m_pMarshal->localIp()),&(m_pMarshal->localPort())); + if(!(m_pDescriptor->bActive)) + { + m_pDescriptor->szIp = m_pMarshal->remoteIp(); + m_pDescriptor->szPort = m_pMarshal->remotePort(); + m_pDescriptor->szHost = m_pMarshal->remoteIp(); + } + updateCaption(); + + connect(m_pUpdateTimer,SIGNAL(timeout()),this,SLOT(updateInfo())); + m_pUpdateTimer->start(1000); + + KviDccVoiceThreadOptions * opt = new KviDccVoiceThreadOptions; + + + opt->pCodec = kvi_dcc_voice_get_codec(m_pDescriptor->szCodec.ptr()); + + output(KVI_OUT_DCCMSG,__tr2qs_ctx("Actual codec used is '%s'","dcc"),opt->pCodec->name()); + + opt->bForceHalfDuplex = KVI_OPTION_BOOL(KviOption_boolDccVoiceForceHalfDuplex); +// opt->bForceDummyReadTrigger = false; + opt->iPreBufferSize = KVI_OPTION_UINT(KviOption_uintDccVoicePreBufferSize); + opt->szSoundDevice = KVI_OPTION_STRING(KviOption_stringDccVoiceSoundDevice).toUtf8().data(); + opt->iSampleRate = m_pDescriptor->iSampleRate; + + m_pSlaveThread = new DccVoiceThread(this,m_pMarshal->releaseSocket(),opt); + connect(m_pUpdateTimer,SIGNAL(timeout()),this,SLOT(updateInfo())); + m_pSlaveThread->start(); + + m_pTalkButton->setEnabled(true); +} + +void DccVoiceWindow::stopTalking() +{ + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); + e->setData(new int(0)); + m_pSlaveThread->enqueueEvent(e); +} + +void DccVoiceWindow::startTalking() +{ + KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); + e->setData(new int(1)); + m_pSlaveThread->enqueueEvent(e); +} + +void DccVoiceWindow::startOrStopTalking(bool bStart) +{ + if(bStart)startTalking(); + else stopTalking(); +} + +int DccVoiceWindow::getMixerVolume(void) const +{ +#ifndef COMPILE_DISABLE_DCC_VOICE + int fd; + int ret; + int left; //, right; + int req; + + if((fd = ::open(KVI_OPTION_STRING(KviOption_stringDccVoiceMixerDevice).toUtf8().data(), O_RDONLY)) == -1) + { + return 0; + } + + req = KVI_OPTION_BOOL(KviOption_boolDccVoiceVolumeSliderControlsPCM) ? SOUND_MIXER_READ_PCM : SOUND_MIXER_READ_VOLUME; + + if(::ioctl(fd,req,&ret)) + { + ::close(fd); + return 0; + } + + left = (ret & 0x00ff); +// right = (ret & 0xff00) >> 8; + + ::close(fd); + + return -left; +#else + return 0; +#endif +} + +void DccVoiceWindow::setMixerVolume(int vol) +{ +#ifndef COMPILE_DISABLE_DCC_VOICE + int fd; + int val; + int req; + + if((fd = ::open(KVI_OPTION_STRING(KviOption_stringDccVoiceMixerDevice).toUtf8().data(), O_WRONLY)) == -1) + return; + + req = KVI_OPTION_BOOL(KviOption_boolDccVoiceVolumeSliderControlsPCM) ? SOUND_MIXER_WRITE_PCM : SOUND_MIXER_WRITE_VOLUME; + + val = (-vol << 8) | -vol; + ::ioctl(fd, req, &val); + ::close(fd); + + m_pVolumeSlider->setToolTip(__tr2qs_ctx("Volume: %1","dcc").arg(-vol)); +#endif +} + + +/* The code below doesn't work. Guess I have to catch some other widget's focusInEvent. Which one ? */ +/* The point is to move the volume slider to correct position if for example user switched to + * another KVirc window, fired up xmms, changed the volume, and returned to our dcc voice window */ +void DccVoiceWindow::focusInEvent(QFocusEvent *e) +{ +// qDebug("focusInEvent()"); + m_pVolumeSlider->setValue(getMixerVolume()); + setMixerVolume(m_pVolumeSlider->value()); + + KviWindow::focusInEvent(e); +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_DccVoiceWindow.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/dcc/DccVoiceWindow.h b/src/modules/dcc/DccVoiceWindow.h new file mode 100644 index 000000000..73af363c0 --- /dev/null +++ b/src/modules/dcc/DccVoiceWindow.h @@ -0,0 +1,443 @@ +#ifndef _VOICE_H_ +#define _VOICE_H_ +//============================================================================= +// +// File : DccVoiceWindow.h +// Creation date : Thu Aug 23 04:08:10 2001 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "DccVoiceCodec.h" +#include "DccDescriptor.h" +#include "DccThread.h" +#include "DccWindow.h" + +#include "KviWindow.h" +#include "KviDataBuffer.h" +#include "kvi_sockettype.h" +#include "KviTalHBox.h" +#include "KviError.h" + +#include +#include +#include + +class QSlider; +class DccMarshal; + +#ifndef _DCC_VOICE_CPP_ + extern bool kvi_dcc_voice_is_valid_codec(const char * codecName); +#endif + +#define KVI_DCC_VOICE_THREAD_ACTION_START_RECORDING 0 +#define KVI_DCC_VOICE_THREAD_ACTION_STOP_RECORDING 1 +#define KVI_DCC_VOICE_THREAD_ACTION_START_PLAYING 2 +#define KVI_DCC_VOICE_THREAD_ACTION_STOP_PLAYING 3 + +typedef struct _KviDccVoiceThreadOptions +{ + bool bForceHalfDuplex; + int iPreBufferSize; + int iSampleRate; + KviCString szSoundDevice; + DccVoiceCodec * pCodec; +} KviDccVoiceThreadOptions; + +class DccVoiceThread : public DccThread +{ + friend class DccVoiceWindow; +public: + DccVoiceThread(KviWindow * wnd,kvi_socket_t fd,KviDccVoiceThreadOptions * opt); + ~DccVoiceThread(); +protected: +// bool m_bUseGsm; + KviDccVoiceThreadOptions * m_pOpt; + int m_soundFd; + int m_soundFdMode; + KviDataBuffer m_outFrameBuffer; + KviDataBuffer m_inFrameBuffer; + KviDataBuffer m_inSignalBuffer; + KviDataBuffer m_outSignalBuffer; + bool m_bPlaying; + bool m_bRecording; + bool m_bRecordingRequestPending; + bool m_bSoundcardChecked; + int m_iLastSignalBufferSize; + long m_iLastSignalBufferTime; +// unsigned int m_uSleepTime; + KviMutex * m_pInfoMutex; + // stuff protected by the mutex: + int m_iInputBufferSize; + int m_iOutputBufferSize; +protected: + bool checkSoundcard(); + bool openSoundcardWithDuplexOption(int openMode,int failMode); + bool openSoundcard(int mode); + bool openSoundcardForWriting(); + bool openSoundcardForReading(); + void closeSoundcard(); + bool readWriteStep(); + bool soundStep(); + void startRecording(); + void stopRecording(); + void startPlaying(); + void stopPlaying(); + virtual void run(); +}; + + +class DccVoiceWindow : public DccWindow +{ + Q_OBJECT +public: + DccVoiceWindow(KviMainWindow *pFrm,DccDescriptor * dcc,const char * name); + ~DccVoiceWindow(); +protected: + KviTalHBox * m_pHBox; + QSlider * m_pVolumeSlider; + QLabel * m_pInputLabel; + QLabel * m_pOutputLabel; + QLabel * m_pRecordingLabel; + QLabel * m_pPlayingLabel; + QToolButton * m_pTalkButton; + QTimer * m_pUpdateTimer; + QString m_szTarget; + DccVoiceThread * m_pSlaveThread; +protected: + virtual void focusInEvent(QFocusEvent *); + virtual const QString & target(); + virtual void fillCaptionBuffers(); + virtual QPixmap * myIconPtr(); + virtual void resizeEvent(QResizeEvent *e); + virtual QSize sizeHint() const; + virtual bool event(QEvent *e); + virtual void getBaseLogFileName(QString &buffer); + void startTalking(); + void stopTalking(); + void startConnection(); + int getMixerVolume(void) const; +protected slots: + void handleMarshalError(KviError::Code eError); + void connected(); + void updateInfo(); + void startOrStopTalking(bool bStart); + void setMixerVolume(int); + void connectionInProgress(); +// void stopTalking(); +}; + +#if 0 + + + +/* + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +CODEC DEFINITION + + Sample rate = samples/sec (ex. 8000) + Sample size = bits (ex. 16 bits) + Sample endianness = le/be + + Sample compressor = name + + ::: + + 8000:16:le:null + 8000:16:le:gsm + 8000:16:le:adpcm + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class KviVoiceParty +{ +public: + KviVoiceParty(const QString &szNick,const QString &szIp,unsigned short uPort); + ~KviVoiceParty(); +protected: + QString m_szIp; + unsigned short m_uPort; + QString m_szNick; + KviPointerList * m_pChildrenTree; +public: + const QString & ip(){ return m_szIp; }; + unsigned short port(){ return m_uPort; }; + const QString & nick(){ return m_szNick; }; + void addChild(KviVoiceParty * pChild); +}; + + +KviVoiceParty::KviVoiceParty(const QString &szNick,const QString &szIp,unsigned short uPort) +: m_szIp(szIp), m_uPort(uPort), m_szNick(szNick) +{ + m_pChildrenTree = 0; +} + +KviVoiceParty::~KviVoiceParty() +{ + if(m_pChildrenTree)delete m_pChildrenTree; +} + +void KviVoiceParty::addChild(KviVoiceParty * pChild) +{ + if(!m_pChildrenTree) + { + m_pChildrenTree = new KviPointerList; + m_pChildrenTree->setAutoDelete(true); + } + m_pChildrenTree->append(pChild); +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class KviVoiceAudioEncoder +{ +public: + KviVoiceAudioEncoder(); + ~KviVoiceAudioEncoder(); +public: + +}; + +class KviVoiceAudioDecoder +{ +public: + KviVoiceAudioDecoder(); + ~KviVoiceAudioDecoder(); +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class KviVoiceLink +{ +public: + KviVoiceLink(KviVoiceParty * pRemoteParty); + ~KviVoiceLink(); +protected: + QString m_szId; + KviVoiceParty * m_pRemoteParty; + KviVoiceAudioEncoder * m_pAudioEncoder; + KviVoiceAudioDecoder * m_pAudioDecoder; +public: + const QStirng & id(){ return m_szId; }; + KviVoiceParty * remoteParty(){ return m_pRemoteParty; }; +}; + +KviVoiceLink::KviVoiceLink(KviVoiceParty * pRemoteParty) +{ + KviQString::sprintf("%Q:%u",&(pRemoteParty->nick()),pRemoteParty->port()); + m_pRemoteParty = pRemoteParty; + m_pAudioEncoder = 0; + m_pAudioDecoder = 0; +} + +KviVoiceLink::~KviVoiceLink() +{ + delete m_pRemoteParty; + if(m_pAudioEncoder)delete m_pAudioEncoder; + if(m_pAudioDecoder)delete m_pAudioDecoder; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class KviVoice_r8000s16eL_to_r8000s16eB_Transformer +{ + +} + +class KviVoice_r8000s16eB_to_r8000s16eL_Transformer +{ + +} + +class KviVoice_r11025s16eL_to_r11025s16eB_Transformer +{ + +} + +class KviVoice_r11025s16eB_to_r11025s16eL_Transformer +{ + +} + +class KviVoice_r11025s16eL_to_r8000s16eL_Transformer +{ + +} + +class KviVoice_r11025s16eL_to_r8000s16eB_Transformer +{ + +} + +class KviVoice_r11025s16eB_to_r8000s16eL_Transformer +{ + +} + +class KviVoice_r8000s16eL_to_r11025s16eL_Transformer +{ + +} + +class KviVoice_r8000s16eL_to_r11025s16eB_Transformer +{ + +} + +class KviVoice_r8000s16eB_to_r11025s16eL_Transformer +{ + +} + + + +class KviVoiceConference +{ +public: + KviVoiceConference(); + ~KviVoiceConference(); +public: + KviPointerList * m_pLinks; + KviPointerHashTable * + SOCKET m_hUdpSocket; + QString m_szLastError; + + unsigned int m_uLocalAudioSampleRate; // samples/sec + unsigned int m_uLocalAudioSampleSize; // bits + unsigned int m_uLocalAudioEndianness; // 0 = le, 1 = be + +public: + void conferenceThread(); +protected: + void conferenceThreadMain(); + bool setupUdpSocket(); +}; + +KviVoiceConference::KviVoiceConference() +{ + m_pLinks = new KviPointerList; + m_pLinks->setAutoDelete(true); +} + +KviVoiceConference::~KviVoiceConference() +{ + delete m_pLinks; +} + +bool KviVoiceConference::setupUdpSocket() +{ + return true; +} + +void KviVoiceConference::shutdownUdpSocket() +{ +} + +void KviVoiceConference::conferenceThreadMain() +{ + for(;;) + { + readAndDecompressIncomingDataForEveryLink(); + + mixIncomingDataToASingleStream(); + playIncomingDataSingleStream(); + + readLocalAudioStream(); + + foreach(link) + { + mixLocalAndOtherIncomingDataStreams() + compressAndSendOtherIncomingDataStreams() + } + + } +} + +void KviVoiceConference::conferenceThread() +{ + if(!setupUdpSocket())return; + + conferenceThreadMain(); + + shutdownUdpSocket(); +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +*/ + +// DCC VOICE NG proto + +// +// tcp control connection +// --> HELLO: DccVoice protocol header +// <-- HELLO: DccVoice protocol header +// --> IACCEPT: Codec-description|CodecId,Codec-description|CodecID,Codec... (in order of preference) +// <-- IACCEPT: Codec-description|CodecID,Codec-description|CodecId,Codec... (in order of preference) +// --> MYADDRESS +// <-- MYADDRESS +// --> YOURIDIS: (CID) +// <-- YOURIDIS: (CID) + +// Audio is sent in blocks broken in chunks broken in udp packets +// Each block is a set of consecutive audio chunks that theoretically +// should be played consecutively. +// Each packet in a chunk has an ordinal +// Chunks must be relatively short in order +// to allow a remote end that looses a packet to +// synchronize after a short period of time +// The maximum number of packets in a chunk is 65535 (but a chunk should be no more than 24-32 KBytes in size +// and in general they should be as small as possible, even one packet per chunk, if the codec allows it) +// Each chunk should be encoded independently of the others +// We can switch codec at each chunk (but not at each packet) +// When some packets are lost we loose the entire chunk +// A block is completly synchronized in time (unless we loose some chunks: in that case +// we may decide to synchronize with silence or insert a glitch...) +// Decoding never depends on the future + +// Each packet should be decompressable (eventually dependently on the previous in the chunk) +// but playable independently + +// start UDP stream + +// UDP Packet format: + +// : byte +// : byte +// : word +// : word +// + + +// Payload format: + +// : word +// : word (0 = beginning of a chunk) + +// read raw audio data at sample rate X, sample size Y +// multiplex data always at this sample rate and sample size + + +#endif + +#endif //_VOICE_H_ diff --git a/src/modules/dcc/DccWindow.cpp b/src/modules/dcc/DccWindow.cpp new file mode 100644 index 000000000..e6da3fa12 --- /dev/null +++ b/src/modules/dcc/DccWindow.cpp @@ -0,0 +1,58 @@ +//============================================================================= +// +// File : DccWindow.cpp +// Creation date : Fri Jul 26 02:04:40 2002 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "DccWindow.h" + +#include "KviTalHBox.h" + +DccWindow::DccWindow(int type,KviMainWindow * lpFrm,const char * name,DccDescriptor * d) +: KviWindow(type,lpFrm,name, d->console()) +{ + m_pDescriptor = d; + m_pDescriptor->setWindow(this); + m_pMarshal = 0; + m_pButtonBox = new KviTalHBox(this); + createTextEncodingButton(m_pButtonBox); +} + +DccWindow::~DccWindow() +{ + if(m_pMarshal)delete m_pMarshal; + if(m_pDescriptor)delete m_pDescriptor; +} + +KviWindow * DccWindow::dccMarshalOutputWindow() +{ + return this; +} + +const char * DccWindow::dccMarshalOutputContextString() +{ + static const char * static_context = "DCC"; + return static_context; +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_DccWindow.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/dcc/DccWindow.h b/src/modules/dcc/DccWindow.h new file mode 100644 index 000000000..544b17e10 --- /dev/null +++ b/src/modules/dcc/DccWindow.h @@ -0,0 +1,50 @@ +#ifndef _WINDOW_H_ +#define _WINDOW_H_ +//============================================================================= +// +// File : DccWindow.h +// Creation date : Fri Jul 26 02:04:39 2002 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "DccDescriptor.h" +#include "DccMarshal.h" + +#include "KviWindow.h" +class DccThread; + +class DccWindow : public KviWindow, public DccMarshalOutputContext +{ + Q_OBJECT +public: + DccWindow(int type,KviMainWindow * lpFrm,const char * name,DccDescriptor * d); + ~DccWindow(); +protected: + DccDescriptor * m_pDescriptor; + DccMarshal * m_pMarshal; +public: + DccDescriptor * descriptor() { return m_pDescriptor; }; + const DccMarshal * marshal() { return m_pMarshal; }; + virtual DccThread * getSlaveThread() { return 0; }; + virtual KviWindow * dccMarshalOutputWindow(); + virtual const char * dccMarshalOutputContextString(); +}; + +#endif //_WINDOW_H_ diff --git a/src/modules/dcc/adpcmcodec.cpp b/src/modules/dcc/adpcmcodec.cpp deleted file mode 100644 index 4e9f45f13..000000000 --- a/src/modules/dcc/adpcmcodec.cpp +++ /dev/null @@ -1,306 +0,0 @@ -//============================================================================= -// -// File : adpcmcodec.h -// Creation date : Wed Aug 22 19:12:46 2001 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= -// -// Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The Netherlands. -// All Rights Reserved -// -// Permission to use, copy, modify, and distribute this software and its -// documentation for any purpose and without fee is hereby granted, -// provided that the above copyright notice appear in all copies and that -// both that copyright notice and this permission notice appear in -// supporting documentation, and that the names of Stichting Mathematisch -// Centrum or CWI not be used in advertising or publicity pertaining to -// distribution of the software without specific, written prior permission. -// -// STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO -// THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -// FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE -// FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -// OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// -// Intel/DVI ADPCM coder/decoder. -// -// The algorithm for this coder was taken from the IMA Compatability Project -// proceedings, Vol 2, Number 2; May 1992. -// -// Version 1.2, 18-Dec-92. -// - -#define _ADPCMCODEC_CPP_ -#include "adpcmcodec.h" - -#include /*DBG*/ - -#ifndef __STDC__ - #define signed -#endif - - - -#define ADPCM_PACKED_FRAME_SIZE_IN_BYTES 512 -#define ADPCM_UNPACKED_FRAME_SIZE_IN_BYTES 2048 -#define ADPCM_UNPACKED_FRAME_SIZE_IN_SHORTS 1024 - -// Intel ADPCM step variation table */ -static int indexTable[16] = { - -1, -1, -1, -1, 2, 4, 6, 8, - -1, -1, -1, -1, 2, 4, 6, 8, -}; - -static int stepsizeTable[89] = { - 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, - 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, - 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, - 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, - 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, - 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, - 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, - 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, - 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 -}; - -void ADPCM_compress(short indata[],char outdata[],int len,ADPCM_state *state) -{ - short *lpIn; /* Input buffer pointer */ - signed char *lpOut; /* output buffer pointer */ - int val; /* Current input sample value */ - int sign; /* Current adpcm sign bit */ - int delta; /* Current adpcm output value */ - int diff; /* Difference between val and valprev */ - int step; /* Stepsize */ - int valpred; /* Predicted output value */ - int vpdiff; /* Current change to valpred */ - int index; /* Current step change index */ - int outputbuffer = 0; /* place to keep previous 4-bit value */ - int bufferstep; /* toggle between outputbuffer/output */ - - lpOut = (signed char *)outdata; - lpIn = indata; - - valpred = state->valprev; - index = state->index; - step = stepsizeTable[index]; - - bufferstep = 1; - - for ( ;len > 0;len-- ) { - val = *lpIn++; - // Step 1 - compute difference with previous value - diff = val - valpred; - sign = (diff < 0) ? 8 : 0; - if(sign)diff=(-diff); - // Step 2 - Divide and clamp - // Note: - // This code *approximately* computes: - // delta = diff*4/step; - // vpdiff = (delta+0.5)*step/4; - // but in shift step bits are dropped. The net result of this is - // that even if you have fast mul/div hardware you cannot put it to - // good use since the fixup would be too expensive. - // - delta = 0; - vpdiff = (step >> 3); - if (diff >=step){ - delta = 4; - diff -= step; - vpdiff += step; - } - step >>= 1; - if (diff >= step) { - delta |= 2; - diff -= step; - vpdiff += step; - } - step >>= 1; - if ( diff >= step ) { - delta |= 1; - vpdiff += step; - } - // Step 3 - Update previous value - if(sign)valpred -= vpdiff; - else valpred += vpdiff; - // Step 4 - Clamp previous value to 16 bits - if ( valpred > 32767 )valpred = 32767; - else if ( valpred < -32768 )valpred = -32768; - // Step 5 - Assemble value, update index and step values - delta |= sign; - index += indexTable[delta]; - if ( index < 0 ) index = 0; - if ( index > 88 ) index = 88; - step = stepsizeTable[index]; - // Step 6 - Output value - if ( bufferstep )outputbuffer = (delta << 4) & 0xf0; - else *lpOut++ = (delta & 0x0f) | outputbuffer; - bufferstep = !bufferstep; - } - // Output last step, if needed - if (!bufferstep)*lpOut++ = outputbuffer; - state->valprev = valpred; - state->index = index; -} - -void ADPCM_uncompress(char indata[],short outdata[],int len,ADPCM_state *state) -{ - signed char *inp; /* Input buffer pointer */ - short *outp; /* output buffer pointer */ - int sign; /* Current adpcm sign bit */ - int delta; /* Current adpcm output value */ - int step; /* Stepsize */ - int valpred; /* Predicted value */ - int vpdiff; /* Current change to valpred */ - int index; /* Current step change index */ - int inputbuffer=0; /* place to keep next 4-bit value */ - int bufferstep; /* toggle between inputbuffer/input */ - - outp = outdata; - inp = (signed char *)indata; - - valpred = state->valprev; - index = state->index; - step = stepsizeTable[index]; - - bufferstep = 0; - - for ( ; len > 0 ; len-- ) { - /* Step 1 - get the delta value */ - if ( bufferstep )delta = inputbuffer & 0xf; - else { - inputbuffer = *inp++; - delta = (inputbuffer >> 4) & 0xf; - } - bufferstep = !bufferstep; - - /* Step 2 - Find new index value (for later) */ - index += indexTable[delta]; - if ( index < 0 ) index = 0; - if ( index > 88 ) index = 88; - - /* Step 3 - Separate sign and magnitude */ - sign = delta & 8; - delta = delta & 7; - - /* Step 4 - Compute difference and new predicted value */ - /* - ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment - ** in adpcm_coder. - */ - vpdiff = step >> 3; - if( delta & 4 )vpdiff += step; - if( delta & 2 )vpdiff += step>>1; - if( delta & 1 )vpdiff += step>>2; - - if(sign)valpred -= vpdiff; - else valpred += vpdiff; - - /* Step 5 - clamp output value */ - if(valpred > 32767)valpred = 32767; - else if(valpred < -32768)valpred = -32768; - - /* Step 6 - Update step value */ - step = stepsizeTable[index]; - - /* Step 7 - Output value */ - *outp++ = valpred; - } - - state->valprev = valpred; - state->index = index; -} - - -KviDccVoiceAdpcmCodec::KviDccVoiceAdpcmCodec() -: KviDccVoiceCodec() -{ - m_pEncodeState = new ADPCM_state; - m_pEncodeState->index = 0; - m_pEncodeState->valprev = 0; - m_pDecodeState = new ADPCM_state; - m_pDecodeState->index = 0; - m_pDecodeState->valprev = 0; - m_szName = "adpcm (compression 1:4)"; -} - -KviDccVoiceAdpcmCodec::~KviDccVoiceAdpcmCodec() -{ - delete m_pEncodeState; - delete m_pDecodeState; -} - -void KviDccVoiceAdpcmCodec::encode(KviDataBuffer * signal,KviDataBuffer * stream) -{ - if(signal->size() < ADPCM_UNPACKED_FRAME_SIZE_IN_BYTES)return; // nothing to encode - - char * ptr = (char *)signal->data(); - - int uFrames = signal->size() / ADPCM_UNPACKED_FRAME_SIZE_IN_BYTES; - int uTotalDataCompressed = uFrames * ADPCM_UNPACKED_FRAME_SIZE_IN_BYTES; - int uFrameOffset = stream->size(); - char * endPtr = ptr + uTotalDataCompressed; - - stream->addSize(ADPCM_PACKED_FRAME_SIZE_IN_BYTES * uFrames); - - while(ptr != endPtr) - { - ADPCM_compress((short *)ptr,(char *)(stream->data() + uFrameOffset),ADPCM_UNPACKED_FRAME_SIZE_IN_SHORTS,m_pEncodeState); - ptr += ADPCM_UNPACKED_FRAME_SIZE_IN_BYTES; - uFrameOffset += ADPCM_PACKED_FRAME_SIZE_IN_BYTES; - } - signal->remove(uTotalDataCompressed); -} - -void KviDccVoiceAdpcmCodec::decode(KviDataBuffer * stream,KviDataBuffer * signal) -{ - if(stream->size() < ADPCM_PACKED_FRAME_SIZE_IN_BYTES)return; // nothing to decode - - char * ptr = (char *)stream->data(); - - // Adpcm codec - int uFrames = stream->size() / ADPCM_PACKED_FRAME_SIZE_IN_BYTES; - int uTotalDataDecompressed = uFrames * ADPCM_PACKED_FRAME_SIZE_IN_BYTES; - int uSignalOffset = signal->size(); - char * endPtr = ptr + (uTotalDataDecompressed); - - signal->addSize(ADPCM_UNPACKED_FRAME_SIZE_IN_BYTES * uFrames); - - while(ptr != endPtr) - { - ADPCM_uncompress((char *)ptr,(short *)(signal->data() + uSignalOffset),ADPCM_UNPACKED_FRAME_SIZE_IN_SHORTS,m_pDecodeState); - ptr += ADPCM_PACKED_FRAME_SIZE_IN_BYTES; - uSignalOffset += ADPCM_UNPACKED_FRAME_SIZE_IN_BYTES; - } - stream->remove(uTotalDataDecompressed); -} - -int KviDccVoiceAdpcmCodec::encodedFrameSize() -{ - return ADPCM_PACKED_FRAME_SIZE_IN_BYTES; -} - -int KviDccVoiceAdpcmCodec::decodedFrameSize() -{ - return ADPCM_UNPACKED_FRAME_SIZE_IN_BYTES; -} diff --git a/src/modules/dcc/adpcmcodec.h b/src/modules/dcc/adpcmcodec.h deleted file mode 100644 index 8843ee893..000000000 --- a/src/modules/dcc/adpcmcodec.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef _ADPCMCODEC_H_ -#define _ADPCMCODEC_H_ -//============================================================================= -// -// File : adpcmcodec.h -// Creation date : Wed Aug 22 19:12:46 2001 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= -// -// adpcm.h - include file for adpcm coder. -// -// Version 1.0, 7-Jul-92. -// -// -// Average compression speed experiment: P166MMX 32MEG -// -// INPUT | OUTPUT | COMPRESSION TIME -// ------------------------------------------------------------------------ -// shorts bytes | bytes | min msec. avrg. high peak (1 time) -// ------------------------------------------------------------------------ -// 512 1024 | 256 | ~4 4 34 -// 1024 2048 | 512 | ~7 8 75 -// 2048 4096 | 1024 | ~13 15 175 (!!!) -// 4096 8192 | 2048 | ~26 33 91 -// 8192 16384 | 4096 | ~57 80 220 (~1 sec of audio) -// 16384 32768 | 8192 | ~110 250 290 -// - -#include // fix for qtextstream.h - -#include "codec.h" - -typedef struct adpcm_state -{ - short valprev; /* Previous output value */ - char index; /* Index into stepsize table */ -} ADPCM_state; - - -class KviDccVoiceAdpcmCodec : public KviDccVoiceCodec -{ -public: - KviDccVoiceAdpcmCodec(); - virtual ~KviDccVoiceAdpcmCodec(); -private: - ADPCM_state * m_pEncodeState; - ADPCM_state * m_pDecodeState; -public: - virtual void encode(KviDataBuffer * signal,KviDataBuffer * stream); - virtual void decode(KviDataBuffer * stream,KviDataBuffer * signal); - virtual int encodedFrameSize(); - virtual int decodedFrameSize(); -}; - - -#endif //_ADPCMCODEC_H_ diff --git a/src/modules/dcc/broker.cpp b/src/modules/dcc/broker.cpp deleted file mode 100644 index db56e1fe7..000000000 --- a/src/modules/dcc/broker.cpp +++ /dev/null @@ -1,994 +0,0 @@ -//============================================================================= -// -// File : broker.cpp -// Creation date : Tue Sep 19 09 2000 10:21:54 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "kvi_settings.h" - -#include "broker.h" -#include "dialogs.h" -#include "chat.h" -#include "send.h" -#include "voice.h" - -#ifndef COMPILE_DISABLE_DCC_VIDEO - #include "video.h" -#endif - -#ifdef COMPILE_DCC_CANVAS - #include "canvas.h" -#endif - -#include "KviApplication.h" -#include "KviMainWindow.h" -#include "KviLocale.h" -#include "KviOptions.h" -#include "KviConsoleWindow.h" -#include "KviFileUtils.h" -#include "kvi_out.h" -#include "KviMediaManager.h" -#include "KviIrcConnection.h" -#include "KviSharedFilesManager.h" - -#include -#include - -// KviApplication.cpp -extern KVIRC_API KviMediaManager * g_pMediaManager; -extern KVIRC_API KviSharedFilesManager * g_pSharedFilesManager; - -//#warning "The broker might lookup the remote host name" - -KviDccBroker::KviDccBroker() -: QObject(0) -{ - setObjectName("dcc_broker"); - KviDccFileTransfer::init(); - - m_pBoxList = new KviPointerList; - m_pBoxList->setAutoDelete(false); - - m_pDccWindowList = new KviPointerList; - m_pDccWindowList->setAutoDelete(false); - - m_pZeroPortTags = new KviPointerHashTable(17); - m_pZeroPortTags->setAutoDelete(true); -} - -KviDccBroker::~KviDccBroker() -{ - delete m_pZeroPortTags; - while(m_pBoxList->first())delete m_pBoxList->first(); - delete m_pBoxList; - m_pBoxList = 0; - while(m_pDccWindowList->first())delete m_pDccWindowList->first(); - delete m_pDccWindowList; - KviDccFileTransfer::done(); -} - - -KviDccZeroPortTag * KviDccBroker::addZeroPortTag() -{ - static unsigned int g_uNextZeroPortTag = 0; - g_uNextZeroPortTag++; - KviDccZeroPortTag * t = new KviDccZeroPortTag; - t->m_tTimestamp = QDateTime::currentDateTime(); - t->m_szTag.setNum(g_uNextZeroPortTag); - //t->m_szTag.prepend("mIrc-zero-port-"); - t->m_uResumePosition = 0; - // FIXME: we should clear this dict if it grows too high.... - m_pZeroPortTags->insert(t->m_szTag,t); - return t; -} - -KviDccZeroPortTag * KviDccBroker::findZeroPortTag(const QString &szTag) -{ - KviDccZeroPortTag * t = m_pZeroPortTags->find(szTag); - if(!t)return 0; - if(t->m_tTimestamp.secsTo(QDateTime::currentDateTime()) > 180) - { - // too late man... - m_pZeroPortTags->remove(szTag); - return 0; - } - return t; -} - -void KviDccBroker::removeZeroPortTag(const QString &szTag) -{ - m_pZeroPortTags->remove(szTag); -} - -unsigned int KviDccBroker::dccBoxCount() -{ - return m_pBoxList->count(); -} - -void KviDccBroker::unregisterDccWindow(KviWindow *wnd) -{ - m_pDccWindowList->removeRef(wnd); -} - -void KviDccBroker::unregisterDccBox(KviDccBox * box) -{ - //qDebug("Forgetting box %d",box); - m_pBoxList->removeRef(box); -} - -void KviDccBroker::cancelDcc(KviDccDescriptor * dcc) -{ - delete dcc; - dcc = 0; -} - -void KviDccBroker::cancelDcc(KviDccBox *box,KviDccDescriptor * dcc) -{ - if(box)box->forgetDescriptor(); - delete dcc; - dcc = 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// RSEND -/////////////////////////////////////////////////////////////////////////////// - -void KviDccBroker::rsendManage(KviDccDescriptor * dcc) -{ - // We need the filename... - QFileInfo fi(dcc->szLocalFileName); - if(fi.exists())rsendExecute(0,dcc); - else rsendAskForFileName(dcc); -} - -void KviDccBroker::rsendAskForFileName(KviDccDescriptor * dcc) -{ - QStringList filenames; - if( - KviFileDialog::askForOpenFileNames(filenames, - __tr2qs_ctx("Choose Files to Send - KVIrc","dcc"),"") - ) { - if(filenames.count() > 0) - { - KviDccDescriptor * d; - QStringList::Iterator it=filenames.begin(); - while(it != filenames.end()) - { - d = new KviDccDescriptor(*dcc); - d->szLocalFileName = *(it); - d->szLocalFileName.trimmed(); - ++it; - if(d->szLocalFileName.isEmpty()) - cancelDcc(d); - else - rsendExecute(d); - } - delete dcc; - } - } else { - cancelDcc(dcc); - } -} - -void KviDccBroker::rsendExecute(KviDccDescriptor * dcc) -{ - if(!g_pApp->windowExists(dcc->console())) - { - // No way...we NEED the right IRC context... - g_pApp->activeConsole()->output(KVI_OUT_DCCERROR, - __tr2qs_ctx("Can't send DCC %Q request to %Q: IRC connection has been terminated","dcc"), - &(dcc->szType),&(dcc->szNick)); - delete dcc; - return; - } - - // Ok...we need the file to exist - QFileInfo fi(dcc->szLocalFileName); - if(!(fi.exists() && fi.isReadable() && (fi.isFile()) && (fi.size() > 0))) - { - dcc->console()->output(KVI_OUT_DCCERROR,__tr2qs_ctx("Can't open file %Q for reading","dcc"), - &(dcc->szLocalFileName)); - delete dcc; - return; - } - - dcc->szFileName = dcc->szLocalFileName; - dcc->szFileName = QFileInfo(dcc->szFileName).fileName(); - - QString fName = dcc->szFileName; - fName.replace(' ',"\\040"); // be cool :) - - QString szTag; - if(dcc->isZeroPortRequest()) - { - // actually we tagged it as "nonempty" in /dcc.rsend --zero-port - // retag it with something more reasonable - KviDccZeroPortTag * t = addZeroPortTag(); - t->m_uFileSize = fi.size(); - dcc->setZeroPortRequestTag(t->m_szTag.toLatin1()); // latin1() should be ok here - szTag = t->m_szTag; - - // DCC [ST]SEND - dcc->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC %s %s 127.0.0.1 0 %u %s%c", - dcc->console()->connection()->encodeText(dcc->szNick).data(), - 0x01, - dcc->console()->connection()->encodeText(dcc->szType).data(), - dcc->console()->connection()->encodeText(fName).data(), - fi.size(), - dcc->console()->connection()->encodeText(szTag).data(), - 0x01); - } else { - dcc->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC %s %s %u%c", - dcc->console()->connection()->encodeText(dcc->szNick).data(), - 0x01, - dcc->console()->connection()->encodeText(dcc->szType).data(), - dcc->console()->connection()->encodeText(fName).data(), - fi.size(),0x01); - szTag = dcc->szFileName; - } - - // now add a file offer, so he we will accept it automatically - // 120 secs is a reasonable timeout - QString szMask = dcc->szNick; - szMask += "!*@*"; - - g_pSharedFilesManager->addSharedFile(szTag,dcc->szLocalFileName,szMask,120); - - delete dcc; -} - -void KviDccBroker::rsendExecute(KviDccBox * box,KviDccDescriptor * dcc) -{ - if(box)box->forgetDescriptor(); - rsendExecute(dcc); -} - - -/////////////////////////////////////////////////////////////////////////////// -// DCC CHAT -/////////////////////////////////////////////////////////////////////////////// - -void KviDccBroker::handleChatRequest(KviDccDescriptor * dcc) -{ - if(!dcc->bAutoAccept) - { - // FIXME: better message ? Secure Direct Client Connection...eventually - // need confirmation - QString tmp = __tr2qs_ctx( \ - "%1 [%2@%3] requests a " \ - "Direct Client Connection in %4 mode.
", \ - "dcc").arg(dcc->szNick, dcc->szUser, dcc->szHost, dcc->szType); - -#ifdef COMPILE_SSL_SUPPORT - if(dcc->bIsSSL)tmp += __tr2qs_ctx("The connection will be secured using SSL.
","dcc"); -#endif - - if(dcc->isZeroPortRequest()) - { - tmp += __tr2qs_ctx( \ - "You will be the passive side of the connection.
" \ - ,"dcc"); - } else { - tmp += __tr2qs_ctx( \ - "The connection target will be host %1 on port %2
" \ - ,"dcc").arg(dcc->szIp, dcc->szPort); - } - - - QString caption = __tr2qs_ctx("DCC %1 Request - KVIrc","dcc").arg(dcc->szType); - - KviDccAcceptBox * box = new KviDccAcceptBox(this,dcc,tmp,caption); - - m_pBoxList->append(box); - connect(box,SIGNAL(accepted(KviDccBox *,KviDccDescriptor *)), - this,SLOT(executeChat(KviDccBox *,KviDccDescriptor *))); - connect(box,SIGNAL(rejected(KviDccBox *,KviDccDescriptor *)), - this,SLOT(cancelDcc(KviDccBox *,KviDccDescriptor *))); - box->show(); - } else { - // auto accept - executeChat(0,dcc); - } -} - -void KviDccBroker::executeChat(KviDccBox *box,KviDccDescriptor * dcc) -{ - if(box)box->forgetDescriptor(); - - if(!g_pApp->windowExists(dcc->console())) - { - // rebind to the first available console.... - dcc->setConsole(g_pApp->activeConsole()); - } - - KviCString szSubProto = dcc->szType; - szSubProto.toLower(); - - QString tmp = QString("dcc: %1 %2@%3:%4").arg(szSubProto.ptr(), dcc->szNick, dcc->szIp, dcc->szPort); - KviDccChat * chat = new KviDccChat(dcc->console()->frame(),dcc,tmp.toUtf8().data()); - - bool bMinimized = dcc->bOverrideMinimize ? dcc->bShowMinimized : \ - (KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccChat) || \ - (dcc->bAutoAccept && KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccChatWhenAutoAccepted))); - - dcc->console()->frame()->addWindow(chat,!bMinimized); - if(bMinimized)chat->minimize(); - m_pDccWindowList->append(chat); -} - -/////////////////////////////////////////////////////////////////////////////// -// ACTIVE VOICE -/////////////////////////////////////////////////////////////////////////////// - -void KviDccBroker::activeVoiceManage(KviDccDescriptor * dcc) -{ - if(!dcc->bAutoAccept) - { - // need confirmation - QString tmp = __tr2qs_ctx( - "%1 [%2@%3] requests a
" \ - "Direct Client Connection in VOICE mode.
" \ - "The connection target will be host %4 on port %5
" \ - ,"dcc" \ - ).arg(dcc->szNick, dcc->szUser, dcc->szHost, dcc->szIp, dcc->szPort); - - KviDccAcceptBox * box = new KviDccAcceptBox(this,dcc,tmp,__tr2qs_ctx("DCC VOICE request","dcc")); - m_pBoxList->append(box); - connect(box,SIGNAL(accepted(KviDccBox *,KviDccDescriptor *)), - this,SLOT(activeVoiceExecute(KviDccBox *,KviDccDescriptor *))); - connect(box,SIGNAL(rejected(KviDccBox *,KviDccDescriptor *)), - this,SLOT(cancelDcc(KviDccBox *,KviDccDescriptor *))); - box->show(); - } else { - // auto accept - activeVoiceExecute(0,dcc); - } -} - -void KviDccBroker::activeVoiceExecute(KviDccBox *box,KviDccDescriptor * dcc) -{ - if(box)box->forgetDescriptor(); - - if(!g_pApp->windowExists(dcc->console())) - { - // rebind to the first available console.... - dcc->setConsole(g_pApp->activeConsole()); - } - - KviCString tmp(KviCString::Format,"dcc: voice %s@%s:%s",dcc->szNick.toUtf8().data(),dcc->szIp.toUtf8().data(),dcc->szPort.toUtf8().data()); - KviDccVoice * v = new KviDccVoice(dcc->console()->frame(),dcc,tmp.ptr()); - - bool bMinimized = dcc->bOverrideMinimize ? dcc->bShowMinimized : \ - (KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccVoice) || \ - (dcc->bAutoAccept && KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccVoiceWhenAutoAccepted))); - - dcc->console()->frame()->addWindow(v,!bMinimized); - if(bMinimized)v->minimize(); - - m_pDccWindowList->append(v); -} - - -/////////////////////////////////////////////////////////////////////////////// -// PASSIVE VOICE -/////////////////////////////////////////////////////////////////////////////// - -void KviDccBroker::passiveVoiceExecute(KviDccDescriptor * dcc) -{ - KviCString tmp(KviCString::Format,"dcc: voice %s@%s:%s",dcc->szNick.toUtf8().data(),dcc->szIp.toUtf8().data(),dcc->szPort.toUtf8().data()); - KviDccVoice * v = new KviDccVoice(dcc->console()->frame(),dcc,tmp.ptr()); - //#warning "Create minimized dcc voice ?... or maybe it's too much ? :)" - bool bMinimized = dcc->bOverrideMinimize ? dcc->bShowMinimized : KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccChat); - dcc->console()->frame()->addWindow(v,!bMinimized); - if(bMinimized)v->minimize(); - m_pDccWindowList->append(v); -} - - -/////////////////////////////////////////////////////////////////////////////// -// ACTIVE VIDEO -/////////////////////////////////////////////////////////////////////////////// - -#ifndef COMPILE_DISABLE_DCC_VIDEO -void KviDccBroker::activeVideoManage(KviDccDescriptor * dcc) -{ - if(!dcc->bAutoAccept) - { - // need confirmation - QString tmp = __tr2qs_ctx( - "%1 [%2@%3] requests a
" \ - "Direct Client Connection in VIDEO mode.
" \ - "The connection target will be host %4 on port %5
" \ - ,"dcc" \ - ).arg(dcc->szNick, dcc->szUser, dcc->szHost, dcc->szIp, dcc->szPort); - - KviDccAcceptBox * box = new KviDccAcceptBox(this,dcc,tmp,__tr2qs_ctx("DCC VIDEO request","dcc")); - m_pBoxList->append(box); - connect(box,SIGNAL(accepted(KviDccBox *,KviDccDescriptor *)), - this,SLOT(activeVideoExecute(KviDccBox *,KviDccDescriptor *))); - connect(box,SIGNAL(rejected(KviDccBox *,KviDccDescriptor *)), - this,SLOT(cancelDcc(KviDccBox *,KviDccDescriptor *))); - box->show(); - } else { - // auto accept - activeVideoExecute(0,dcc); - } -} - -void KviDccBroker::activeVideoExecute(KviDccBox *box,KviDccDescriptor * dcc) -{ - if(box)box->forgetDescriptor(); - - if(!g_pApp->windowExists(dcc->console())) - { - // rebind to the first available console.... - dcc->setConsole(g_pApp->activeConsole()); - } - - KviCString tmp(KviCString::Format,"dcc: video %s@%s:%s",dcc->szNick.toUtf8().data(),dcc->szIp.toUtf8().data(),dcc->szPort.toUtf8().data()); - KviDccVideo * v = new KviDccVideo(dcc->console()->frame(),dcc,tmp.ptr()); - - bool bMinimized = dcc->bOverrideMinimize ? dcc->bShowMinimized : \ - (KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccVideo) || \ - (dcc->bAutoAccept && KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccVideoWhenAutoAccepted))); - - dcc->console()->frame()->addWindow(v,!bMinimized); - if(bMinimized)v->minimize(); - - m_pDccWindowList->append(v); -#else -void KviDccBroker::activeVideoExecute(KviDccBox *,KviDccDescriptor *) -{ -#endif -} - - -/////////////////////////////////////////////////////////////////////////////// -// PASSIVE VIDEO -/////////////////////////////////////////////////////////////////////////////// - -#ifndef COMPILE_DISABLE_DCC_VIDEO -void KviDccBroker::passiveVideoExecute(KviDccDescriptor * dcc) -{ - KviCString tmp(KviCString::Format,"dcc: video %s@%s:%s",dcc->szNick.toUtf8().data(),dcc->szIp.toUtf8().data(),dcc->szPort.toUtf8().data()); - KviDccVideo * v = new KviDccVideo(dcc->console()->frame(),dcc,tmp.ptr()); - //#warning "Create minimized dcc video ?... or maybe it's too much ? :)" - bool bMinimized = dcc->bOverrideMinimize ? dcc->bShowMinimized : KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccChat); - dcc->console()->frame()->addWindow(v,!bMinimized); - if(bMinimized)v->minimize(); - m_pDccWindowList->append(v); -#else -void KviDccBroker::passiveVideoExecute(KviDccDescriptor *) -{ -#endif -} - - -/////////////////////////////////////////////////////////////////////////////// -// ACTIVE CANVAS -/////////////////////////////////////////////////////////////////////////////// - -#ifdef COMPILE_DCC_CANVAS -void KviDccBroker::activeCanvasManage(KviDccDescriptor * dcc) -{ - if(!dcc->bAutoAccept) - { - // need confirmation - QString tmp = __tr2qs_ctx( \ - "%1 [%2@%3] requests a
" \ - "Direct Client Connection in CANVAS mode.
" \ - "The connection target will be host %4 on port %5
" \ - ,"dcc" \ - ).arg(dcc->szNick, dcc->szUser, dcc->szHost, dcc->szIp, dcc->szPort); - - KviDccAcceptBox * box = new KviDccAcceptBox(this,dcc,tmp,__tr2qs_ctx("DCC CANVAS request","dcc")); - m_pBoxList->append(box); - connect(box,SIGNAL(accepted(KviDccBox *,KviDccDescriptor *)), - this,SLOT(activeCanvasExecute(KviDccBox *,KviDccDescriptor *))); - connect(box,SIGNAL(rejected(KviDccBox *,KviDccDescriptor *)), - this,SLOT(cancelDcc(KviDccBox *,KviDccDescriptor *))); - box->show(); - } else { - // auto accept - activeCanvasExecute(0,dcc); - } -} -#endif - -#ifdef COMPILE_DCC_CANVAS -void KviDccBroker::activeCanvasExecute(KviDccBox *box,KviDccDescriptor * dcc) -{ - if(box)box->forgetDescriptor(); - - if(!g_pApp->windowExists(dcc->console())) - { - // rebind to the first available console.... - dcc->setConsole(g_pApp->activeConsole()); - } - - KviCString tmp(KviCString::Format,"dcc: canvas %s@%s:%s",dcc->szNick.toUtf8().data(),dcc->szIp.toUtf8().data(),dcc->szPort.toUtf8().data()); - KviDccCanvas * cnv = new KviDccCanvas(dcc->console()->frame(),dcc,tmp.ptr()); - - //#warning "This option should be dedicated to Dcc Canvas!....for now we are using the DccChat options" - bool bMinimized = dcc->bOverrideMinimize ? dcc->bShowMinimized : \ - (KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccChat) || \ - (dcc->bAutoAccept && KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccChatWhenAutoAccepted))); - - dcc->console()->frame()->addWindow(cnv,!bMinimized); - if(bMinimized)cnv->minimize(); - - m_pDccWindowList->append(cnv); -#else -void KviDccBroker::activeCanvasExecute(KviDccBox *,KviDccDescriptor *) -{ -#endif -} - -/////////////////////////////////////////////////////////////////////////////// -// PASSIVE CANVAS -/////////////////////////////////////////////////////////////////////////////// -#ifdef COMPILE_DCC_CANVAS -void KviDccBroker::passiveCanvasExecute(KviDccDescriptor * dcc) -{ - KviCString tmp(KviCString::Format,"dcc: canvas %s@%s:%s",dcc->szNick.toUtf8().data(),dcc->szIp.toUtf8().data(),dcc->szPort.toUtf8().data()); - KviDccCanvas * cnv = new KviDccCanvas(dcc->console()->frame(),dcc,tmp.ptr()); - //#warning "This option should be dedicated to Dcc Canvas!....for now we are using the DccChat options" - bool bMinimized = dcc->bOverrideMinimize ? dcc->bShowMinimized : KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccChat); - dcc->console()->frame()->addWindow(cnv,!bMinimized); - if(bMinimized)cnv->minimize(); - m_pDccWindowList->append(cnv); -} -#endif - -/////////////////////////////////////////////////////////////////////////////// -// SEND -/////////////////////////////////////////////////////////////////////////////// - -void KviDccBroker::recvFileManage(KviDccDescriptor * dcc) -{ - if(dcc->bIsIncomingAvatar) - { - bool bOk; - quint64 size = dcc->szFileSize.toULongLong(&bOk); - if(bOk) { - if(size>=KVI_OPTION_UINT(KviOption_uintMaximumRequestedAvatarSize)) { - cancelDcc(0,dcc); - return; - } - } - } - - if(!dcc->bAutoAccept) - { - // need confirmation - QString tmp; - - if(dcc->bActive) - { - // Normal active send: we will be connecting - tmp = __tr2qs_ctx( \ - "%1 [%2@%3] " \ - "wants to send you the file " \ - "'%4', " \ - "%5 large.
" \ - "The connection target will be host %6 on port %7
" \ - ,"dcc" \ - ).arg(dcc->szNick, dcc->szUser, dcc->szHost, dcc->szFileName, - KviQString::makeSizeReadable(dcc->szFileSize.toULongLong()), - dcc->szIp, dcc->szPort); - - } else { - // passive: we will be listening! - tmp = __tr2qs_ctx( \ - "%1 [%2@%3] " - "wants to send you the file " \ - "'%4', " \ - "%5 large.
" \ - "You will be the passive side of the connection.
" \ - ,"dcc" \ - ).arg(dcc->szNick, dcc->szUser, dcc->szHost, dcc->szFileName, - KviQString::makeSizeReadable(dcc->szFileSize.toULongLong())); - } - - if(dcc->bIsIncomingAvatar) - { - tmp += __tr2qs_ctx( \ - "
Note:
" \ - "The file appears to be an avatar that you have requested. " \ - "You should not change its filename. " \ - "Save it in a location where KVIrc can find it, such as " \ - "the 'avatars', 'incoming', or 'pics' directories, " \ - "your home directory, or the save directory for the incoming file type. " \ - "The default save path will probably work. " \ - "You can instruct KVIrc to accept incoming avatars automatically " \ - "by setting the option boolAutoAcceptIncomingAvatars to true.
" \ - ,"dcc" \ - ); - } - - //#warning "Maybe remove the pending avatar if rejected ?" - - QString title = __tr2qs_ctx("DCC %1 Request - KVIrc","dcc").arg(dcc->szType); - - KviDccAcceptBox * box = new KviDccAcceptBox(this,dcc,tmp,title); - m_pBoxList->append(box); - connect(box,SIGNAL(accepted(KviDccBox *,KviDccDescriptor *)), - this,SLOT(chooseSaveFileName(KviDccBox *,KviDccDescriptor *))); - connect(box,SIGNAL(rejected(KviDccBox *,KviDccDescriptor *)), - this,SLOT(cancelDcc(KviDccBox *,KviDccDescriptor *))); - box->show(); - } else { - // auto accept - if(_OUTPUT_VERBOSE) - { - dcc->console()->output(KVI_OUT_DCCMSG,__tr2qs_ctx("Auto-accepting DCC %Q request from %Q!%Q@%Q for file %Q","dcc"), - &(dcc->szType),&(dcc->szNick),&(dcc->szUser), - &(dcc->szHost),&(dcc->szFileName)); - } - chooseSaveFileName(0,dcc); - } -} - -void KviDccBroker::chooseSaveFileName(KviDccBox *box,KviDccDescriptor *dcc) -{ - if(box)box->forgetDescriptor(); - - // Lookup the suggested save directory - - dcc->szLocalFileName = ""; - - if(dcc->bIsIncomingAvatar)g_pApp->getLocalKvircDirectory(dcc->szLocalFileName,KviApplication::Avatars); - else { - - if(KVI_OPTION_BOOL(KviOption_boolUseIncomingDccMediaTypeSavePath)) - { - g_pMediaManager->lock(); - if(KviMediaType * mt = g_pMediaManager->findMediaType(dcc->szFileName.toUtf8().data(),false)) - { - if(mt->szSavePath.hasData()) - { - if(KviFileUtils::directoryExists(mt->szSavePath.ptr()))dcc->szLocalFileName = mt->szSavePath; - else { - if(KviFileUtils::makeDir(mt->szSavePath.ptr()))dcc->szLocalFileName = mt->szSavePath; - } - if(KVI_OPTION_BOOL(KviOption_boolSortReceivedByDccFilesByNicks)) - { - KviQString::ensureLastCharIs(dcc->szLocalFileName,KVI_PATH_SEPARATOR_CHAR); - QString cleanNick = dcc->szNick; - KviFileUtils::cleanFileName(cleanNick); - dcc->szLocalFileName.append(cleanNick); - KviFileUtils::adjustFilePath(dcc->szLocalFileName); - } - KviFileUtils::makeDir(dcc->szLocalFileName); - } - } - g_pMediaManager->unlock(); - } - - if(dcc->szLocalFileName.isEmpty()) - { - g_pApp->getLocalKvircDirectory(dcc->szLocalFileName,KviApplication::Incoming); - if(KVI_OPTION_BOOL(KviOption_boolSortReceivedByDccFilesByNicks)) - { - KviQString::ensureLastCharIs(dcc->szLocalFileName,KVI_PATH_SEPARATOR_CHAR); - QString cleanNick = dcc->szNick; - KviFileUtils::cleanFileName(cleanNick); - dcc->szLocalFileName.append(cleanNick); - KviFileUtils::adjustFilePath(dcc->szLocalFileName); - KviFileUtils::makeDir(dcc->szLocalFileName); - } - } - } - KviFileUtils::adjustFilePath(dcc->szLocalFileName); - KviQString::ensureLastCharIs(dcc->szLocalFileName,KVI_PATH_SEPARATOR_CHAR); - - if(!(dcc->bAutoAccept)) - { - QString cleanFilename = dcc->szFileName; - KviFileUtils::cleanFileName(cleanFilename); - dcc->szLocalFileName.append(cleanFilename); - if(KviFileDialog::askForSaveFileName(dcc->szLocalFileName, - __tr2qs_ctx("Choose Files to Save - KVIrc","dcc"),dcc->szLocalFileName)) - { - renameOverwriteResume(0,dcc); - } else { - cancelDcc(dcc); - } - } else { - // auto accept - // WE choose the filename - QString cleanFilename = dcc->szFileName; - KviFileUtils::cleanFileName(cleanFilename); - dcc->szLocalFileName.append(cleanFilename); - - if(_OUTPUT_VERBOSE) - { - dcc->console()->output(KVI_OUT_DCCMSG,__tr2qs_ctx("Auto-saving DCC %Q file %Q as \r![!dbl]play $0\r%Q\r","dcc"), - &(dcc->szType),&(dcc->szFileName),&(dcc->szLocalFileName)); - } - - renameOverwriteResume(0,dcc); - } -} - -void KviDccBroker::renameOverwriteResume(KviDccBox *box,KviDccDescriptor * dcc) -{ - if(box)box->forgetDescriptor(); - - // Check if file exists - QFileInfo fi(dcc->szLocalFileName); - if(fi.exists() && (fi.size() > 0)) // 0 byte files are senseless for us - { - dcc->szLocalFileSize.setNum(fi.size()); - - bool bOk; - quint64 iRemoteSize = dcc->szFileSize.toULongLong(&bOk); - if(!bOk) - iRemoteSize = 0; - - if(!dcc->bAutoAccept) - { - QString tmp; - bool bDisableResume = false; - - if( - (!bOk) || // remote size is unknown - (iRemoteSize > (quint64)fi.size()) // or it is larger than the actual size on disk - ) - { - tmp = __tr2qs_ctx( \ - "The file '%1' already exists " \ - "and is %2 large.
" \ - "Do you wish to
" \ - "auto-rename the new file,
" \ - "overwrite the existing file, or
" \ - "resume an incomplete download?" \ - ,"dcc" \ - ).arg(dcc->szLocalFileName, KviQString::makeSizeReadable(fi.size())); - } else { - bDisableResume = true; - // the file on disk is larger or equal to the remote one - tmp = __tr2qs_ctx( \ - "The file '%1' already exists " \ - "and is larger than the offered one.
" \ - "Do you wish to
" \ - "auto-rename the new file, or
" \ - "overwrite the existing file ?" \ - ,"dcc" \ - ).arg(dcc->szLocalFileName); - } - - KviDccRenameBox * box = new KviDccRenameBox(this,dcc,tmp,bDisableResume); - m_pBoxList->append(box); - connect(box,SIGNAL(renameSelected(KviDccBox *,KviDccDescriptor *)), - this,SLOT(renameDccSendFile(KviDccBox *,KviDccDescriptor *))); - connect(box,SIGNAL(overwriteSelected(KviDccBox *,KviDccDescriptor *)), - this,SLOT(recvFileExecute(KviDccBox *,KviDccDescriptor *))); - connect(box,SIGNAL(cancelSelected(KviDccBox *,KviDccDescriptor *)), - this,SLOT(cancelDcc(KviDccBox *,KviDccDescriptor *))); - box->show(); - return; - } - - // auto resume ? - if( - KVI_OPTION_BOOL(KviOption_boolAutoResumeDccSendWhenAutoAccepted) && - (bOk) && // only if the remote size is really known - (iRemoteSize > (quint64)fi.size()) && // only if the remote size is larger than the local size - (!KviDccFileTransfer::nonFailedTransferWithLocalFileName(dcc->szLocalFileName)) // only if there is no transfer with this local file name yet - ) - { - // yep, auto resume... - dcc->bResume = true; - recvFileExecute(0,dcc); - } else if(iRemoteSize == (quint64)fi.size()) - { - dcc->console()->output(KVI_OUT_DCCMSG,"Transfer aborted: file %Q already completed",&(dcc->szLocalFileName)); - cancelDcc(0,dcc); - } else { - // otherwise auto rename - renameDccSendFile(0,dcc); - } - return; - } - - dcc->szLocalFileSize = "0"; - - // everything OK - recvFileExecute(0,dcc); -} - -void KviDccBroker::renameDccSendFile(KviDccBox *box,KviDccDescriptor * dcc) -{ - if(box)box->forgetDescriptor(); - - - if(QFileInfo(dcc->szLocalFileName).exists()) - { - KviCString szOrig = dcc->szLocalFileName; - int i = 1; - do { - KviCString szNum; - szNum.setNum(i); - int idx = szOrig.findLastIdx('.'); - if(idx != -1) - { - dcc->szLocalFileName = szOrig.left(idx); - dcc->szLocalFileName += "."; - dcc->szLocalFileName += szNum; - dcc->szLocalFileName += szOrig.right(szOrig.len() - idx); - } else { - dcc->szLocalFileName = szOrig; - dcc->szLocalFileName += "."; - dcc->szLocalFileName += szNum; - } - i++; - } while(QFileInfo(dcc->szLocalFileName).exists()); - - if(_OUTPUT_VERBOSE) - { - dcc->console()->output(KVI_OUT_DCCMSG,__tr2qs_ctx("File %s exists, auto-renaming to %Q","dcc"), - szOrig.ptr(),&(dcc->szLocalFileName)); - } - } - - dcc->szLocalFileSize = "0"; // 0 for sure - - recvFileExecute(0,dcc); -} - -void KviDccBroker::recvFileExecute(KviDccBox *box,KviDccDescriptor * dcc) -{ - if(box)box->forgetDescriptor(); - - if(!g_pApp->windowExists(dcc->console())) - { - // rebind to the first available console.... - dcc->setConsole(g_pApp->activeConsole()); - } - - //KviDccSend * send = new KviDccSend(dcc->console()->frame(),dcc,tmp.ptr()); - KviDccFileTransfer * send = new KviDccFileTransfer(dcc); - - bool bMinimized = dcc->bOverrideMinimize ? dcc->bShowMinimized : \ - (KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccSend) || \ - (dcc->bAutoAccept && KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccSendWhenAutoAccepted))); - - send->invokeTransferWindow(dcc->console(),bMinimized,bMinimized); -} - - -void KviDccBroker::sendFileManage(KviDccDescriptor * dcc) -{ - QStringList filenames; - if(KviFileDialog::askForOpenFileNames(filenames,__tr2qs_ctx("Choose Files to Send - KVIrc","dcc"),"")) - { - if(filenames.count() > 0) - { - KviDccDescriptor * d; - QStringList::Iterator it=filenames.begin(); - while(it != filenames.end()) - { - d = new KviDccDescriptor(*dcc); - d->szLocalFileName = *(it); - d->szLocalFileName.trimmed(); - ++it; - if(d->szLocalFileName.isEmpty()) - cancelDcc(d); - else - sendFileExecute(0,d); - } - delete dcc; - } - } else { - cancelDcc(dcc); - } -} - -void KviDccBroker::sendFileExecute(KviDccBox * box,KviDccDescriptor *dcc) -{ - if(box)box->forgetDescriptor(); - - if(!g_pApp->windowExists(dcc->console())) - { - // rebind to the first available console.... - dcc->setConsole(g_pApp->activeConsole()); - } - - QFileInfo fi(dcc->szLocalFileName); - if(!(fi.exists() && fi.isReadable() && (fi.isFile()) && (fi.size() > 0))) - { - dcc->console()->output(KVI_OUT_DCCERROR,__tr2qs_ctx("Can't open file %Q for reading","dcc"), - &(dcc->szLocalFileName)); - delete dcc; - return; - } - - dcc->szFileName = dcc->szLocalFileName; - dcc->szFileName = QFileInfo(dcc->szFileName).fileName(); - - dcc->szLocalFileSize.setNum(fi.size()); - - KviDccFileTransfer * send = new KviDccFileTransfer(dcc); - - bool bMinimized = dcc->bOverrideMinimize ? dcc->bShowMinimized : KVI_OPTION_BOOL(KviOption_boolCreateMinimizedDccSend); - - send->invokeTransferWindow(dcc->console(),bMinimized,bMinimized); -} - -bool KviDccBroker::canUnload() -{ - if(m_pBoxList) - { - if((m_pBoxList->count() != 0) || - (m_pDccWindowList->count() != 0) || - (KviDccFileTransfer::transferCount() != 0))return false; - } // else in the destructor anyway (going to die) - return true; -} - -bool KviDccBroker::handleResumeAccepted(const char * filename,const char * port,const char * szZeroPortTag) -{ - return KviDccFileTransfer::handleResumeAccepted(filename,port,szZeroPortTag); -} - -bool KviDccBroker::handleResumeRequest(KviDccRequest * dcc,const char * filename,const char * port,unsigned long filePos,const char * szZeroPortTag) -{ - //qDebug("HANDLE %s %s %u %s",filename,port,filePos,szZeroPortTag); - // the zeroPOrtTag is nonempty here only if port == 0 - if(kvi_strEqualCI("0",port) && szZeroPortTag) - { - // zero port resume request (we have sent out a DCC SEND 0 - KviDccZeroPortTag * t = findZeroPortTag(QString(szZeroPortTag)); - if(t) - { - // valid zero port resume request - if(filePos >= t->m_uFileSize) - return false; // invalid resume size - - // ok! - t->m_uResumePosition = filePos; - - KviCString szBuffy; - KviIrcServerParser::encodeCtcpParameter(filename,szBuffy); - - dcc->ctcpMsg->msg->console()->connection()->sendFmtData( - "PRIVMSG %s :%cDCC ACCEPT %s %s %u %s%c", - dcc->ctcpMsg->msg->console()->connection()->encodeText(dcc->ctcpMsg->pSource->nick()).data(), - 0x01, - szBuffy.ptr(), - port, - filePos, - szZeroPortTag, - 0x01 - ); - - return true; - } - } - //qDebug("NOT A ZeRO PORT"); - - return KviDccFileTransfer::handleResumeRequest(filename,port,filePos); -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_broker.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/dcc/broker.h b/src/modules/dcc/broker.h deleted file mode 100644 index 5f69a4c3d..000000000 --- a/src/modules/dcc/broker.h +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef _BROKER_H_ -#define _BROKER_H_ -//============================================================================= -// -// File : broker.h -// Creation date : Tue Sep 19 09 2000 10:20:01 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "descriptor.h" - -#include "kvi_settings.h" -#include "KviCString.h" -#include "KviPointerList.h" -#include "KviIrcServerParser.h" -#include "KviPointerHashTable.h" - -#include -#include - -class KviConsoleWindow; -class KviDccBroker; -class KviWindow; -class KviDccBox; - -// #define COMPILE_DCC_CANVAS - - -class KviDccZeroPortTag -{ -public: - QDateTime m_tTimestamp; - QString m_szTag; - unsigned long m_uFileSize; // outgoing file size, valid only for file transfers obviously - unsigned long m_uResumePosition; // if 0 = no resume, valid only for file transfers obviously -}; - -class KviDccBroker : public QObject -{ - Q_OBJECT -public: - KviDccBroker(); - ~KviDccBroker(); -protected: - KviPointerList * m_pBoxList; - KviPointerList * m_pDccWindowList; - KviPointerHashTable * m_pZeroPortTags; -public: - KviDccZeroPortTag * addZeroPortTag(); - KviDccZeroPortTag * findZeroPortTag(const QString &szTag); - void removeZeroPortTag(const QString &szTag); - - unsigned int dccWindowsCount(){ return m_pDccWindowList->count(); }; - unsigned int dccBoxCount(); - - void unregisterDccBox(KviDccBox * box); - void unregisterDccWindow(KviWindow *dcc); - - void rsendManage(KviDccDescriptor * dcc); - void rsendAskForFileName(KviDccDescriptor * dcc); - - void handleChatRequest(KviDccDescriptor * dcc); - -#ifdef COMPILE_DCC_CANVAS - void activeCanvasManage(KviDccDescriptor * dcc); - void passiveCanvasExecute(KviDccDescriptor * dcc); -#endif - - void activeVoiceManage(KviDccDescriptor * dcc); - void passiveVoiceExecute(KviDccDescriptor * dcc); - - void activeVideoManage(KviDccDescriptor * dcc); - void passiveVideoExecute(KviDccDescriptor * dcc); - - void recvFileManage(KviDccDescriptor * dcc); - void sendFileManage(KviDccDescriptor * dcc); - - bool handleResumeAccepted(const char * filename,const char * port,const char * szZeroPortTag); - bool handleResumeRequest(KviDccRequest * dcc,const char * filename,const char * port,unsigned long filePos,const char * szZeroPortTag); - -public slots: - void rsendExecute(KviDccBox * box,KviDccDescriptor * dcc); - void rsendExecute(KviDccDescriptor * dcc); - -// void activeChatExecute(KviDccBox * box,KviDccDescriptor * dcc); - void executeChat(KviDccBox * box,KviDccDescriptor * dcc); - - void activeCanvasExecute(KviDccBox * box,KviDccDescriptor * dcc); - void activeVoiceExecute(KviDccBox * box,KviDccDescriptor * dcc); - void activeVideoExecute(KviDccBox * box,KviDccDescriptor * dcc); - - void sendFileExecute(KviDccBox * box,KviDccDescriptor * dcc); - void recvFileExecute(KviDccBox * box,KviDccDescriptor * dcc); - - void chooseSaveFileName(KviDccBox *box,KviDccDescriptor * dcc); - void renameOverwriteResume(KviDccBox *box,KviDccDescriptor * dcc); - void renameDccSendFile(KviDccBox *box,KviDccDescriptor * dcc); - - void cancelDcc(KviDccBox *box,KviDccDescriptor * dcc); - void cancelDcc(KviDccDescriptor * dcc); - -public: - bool canUnload(); -}; - -#endif diff --git a/src/modules/dcc/canvas.cpp b/src/modules/dcc/canvas.cpp deleted file mode 100644 index a9f943371..000000000 --- a/src/modules/dcc/canvas.cpp +++ /dev/null @@ -1,301 +0,0 @@ -//============================================================================= -// -// File : canvas.cpp -// Creation date : Sun Jul 29 07 2001 20:23:13 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#define QT_MODULE_CANVAS - -#include "canvas.h" - -#ifdef COMPILE_DCC_CANVAS - - #include "dialogs.h" - #include "marshal.h" - #include "canvaswidget.h" - - #define _KVI_DEBUG_CHECK_RANGE_ - #include "kvi_debug.h" - #include "KviOptions.h" - #include "KviInput.h" - #include "KviIrcView.h" - #include "KviIconManager.h" - #include "KviLocale.h" - #include "KviError.h" - #include "kvi_out.h" - #include "KviNetUtils.h" - #include "KviConsoleWindow.h" - #include "KviMainWindow.h" - #include "KviMemory.h" - #include "KviMemory.h" - #include "KviThread.h" - #include "KviIrcSocket.h" - #include "kvi_settings.h" - #include "KviIrcConnection.h" - - #include - - extern KviDccBroker * g_pDccBroker; - - - KviDccCanvas::KviDccCanvas(KviMainWindow *pFrm,KviDccDescriptor * dcc,const char * name) - : KviDccWindow(KVI_WINDOW_TYPE_DCCCANVAS,pFrm,name,dcc) - { - m_pSplitter = new QSplitter(QSplitter::Vertical,this,"splitter"); - - m_pCanvas = new KviCanvasWidget(m_pSplitter); - - m_pIrcView = new KviIrcView(m_pSplitter,pFrm,this); - m_pInput = new KviInput(this); - - // setFocusHandler(m_pInput,this); - - m_pMarshal = new KviDccMarshal(this); - connect(m_pMarshal,SIGNAL(error(int)),this,SLOT(handleMarshalError(int))); - connect(m_pMarshal,SIGNAL(connected()),this,SLOT(connected())); - - - if(!(m_pDescriptor->bActive)) - { - // PASSIVE CONNECTION - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Attempting a passive DCC CANVAS connection","dcc")); - int ret = m_pMarshal->dccListen(dcc->szListenIp,dcc->szListenPort,m_pDescriptor->bDoTimeout); - if(ret != KviError_success)handleMarshalError(ret); - else { - - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Listening on interface %Q port %Q","dcc"), - &(m_pMarshal->localIp()),&(m_pMarshal->localPort())); - - if(dcc->bSendRequest) - { - QString ip = !dcc->szFakeIp.isEmpty() ? dcc->szFakeIp : dcc->szListenIp; - QString port = !dcc->szFakePort.isEmpty() ? dcc->szFakePort.toUtf8().data() : m_pMarshal->localPort(); - //#warning "OPTION FOR SENDING 127.0.0.1 and so on (not an unsigned number)" - struct in_addr a; - if(kvi_stringIpToBinaryIp(ip.toUtf8().data(),&a))ip.setNum(htonl(a.s_addr)); - dcc->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC CANVAS chat %Q %Q%c", - dcc->console()->connection()->encodeText( dcc->szNick.toUtf8().data() ).data(), - 0x01,&ip, - &port, - 0x01); - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Sent DCC CANVAS request to %Q, waiting for the remote client to connect...","dcc"), - &(dcc->szNick)); - } else outputNoFmt(KVI_OUT_DCCMSG,__tr2qs_ctx("DCC CANVAS request not sent: awaiting manual connections","dcc")); - } - } else { - // ACTIVE CONNECTION - outputNoFmt(KVI_OUT_DCCMSG,__tr2qs_ctx("Attempting an active DCC CANVAS connection","dcc")); - int ret = m_pMarshal->dccConnect(dcc->szIp.toUtf8().data(),dcc->szPort.toUtf8().data(),m_pDescriptor->bDoTimeout); - if(ret != KviError_success)handleMarshalError(ret); - else output(KVI_OUT_DCCMSG,__tr2qs_ctx("Contacting host %Q on port %Q","dcc"),&(dcc->szIp),&(dcc->szPort)); - } - - // m_pSlaveThread = 0; - } - - KviDccCanvas::~KviDccCanvas() - { - g_pDccBroker->unregisterDccWindow(this); - // if(m_pSlaveThread) - // { - // m_pSlaveThread->terminate(); - // delete m_pSlaveThread; - // m_pSlaveThread = 0; - // } - KviThreadManager::killPendingEvents(this); - // delete m_pDescriptor; - // delete m_pMarshal; - } - - const QString & KviDccCanvas::target() - { - // This may change on the fly... - m_szTarget.sprintf("%s@%s:%s", - m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data()); - return m_szTarget; - } - - void KviDccCanvas::fillCaptionBuffers() - { - KviCString tmp(KviCString::Format,"DCC Canvas %s@%s:%s", - m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data()); - - m_szPlainTextCaption = tmp; - - m_szHtmlActiveCaption.sprintf("%s", - KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name().ascii(),tmp.ptr()); - m_szHtmlInactiveCaption.sprintf("%s", - KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name().ascii(),tmp.ptr()); - } - - QPixmap * KviDccCanvas::myIconPtr() - { - return g_pIconManager->getSmallIcon(KVI_SMALLICON_CANVAS); - } - - void KviDccCanvas::getBaseLogFileName(KviCString &buffer) - { - buffer.sprintf("%s_%s_%s",m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data()); - } - - void KviDccCanvas::ownMessage(const char * text, bool bUserFeedback) - { - KviCString buf(KviCString::Format,"%s\r\n",text); - // m_pSlaveThread->sendRawData(buf.ptr(),buf.len()); - - if(bUserFeedback) - m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG, - m_pDescriptor->szLocalNick.toUtf8().data(),m_pDescriptor->szLocalUser.toUtf8().data(), - m_pDescriptor->szLocalHost.toUtf8().data(),text); - } - - void KviDccCanvas::ownAction(const char * text) - { - KviCString buf(KviCString::Format,"%cACTION %s%c\r\n",text); - // m_pSlaveThread->sendRawData(buf.ptr(),buf.len()); - output(KVI_OUT_ACTION,"%Q %s",&(m_pDescriptor->szLocalNick),text); - } - - bool KviDccCanvas::event(QEvent *e) - { - // if(e->type() == KVI_THREAD_EVENT) - // { - // switch(((KviThreadEvent *)e)->id()) - // { - // case KVI_DCC_THREAD_EVENT_ERROR: - // { - // int * err = ((KviThreadDataEvent *)e)->getData(); - // output(KVI_OUT_DCCERROR,__tr("ERROR: %s"),kvi_getErrorString(*err)); - // delete err; - // return true; - // } - // break; - // case KVI_DCC_THREAD_EVENT_DATA: - // { - // KviCString * d = ((KviThreadDataEvent *)e)->getData(); - // if(d->firstCharIs(0x01)) - // { - // d->cutLeft(1); - // if(d->lastCharIs(0x01))d->cutRight(1); - // if(kvi_strEqualCIN("ACTION",d->ptr(),6))d->cutLeft(6); - // d->stripLeftWhiteSpace(); - // output(KVI_OUT_ACTION,"%s %s",m_pDescriptor->szNick.ptr(),d->ptr()); - // } else { - // - //#ifdef COMPILE_CRYPT_SUPPORT - // if(KviCryptSessionInfo * cinf = cryptSessionInfo()) - // { - // if(cinf->bDoDecrypt) - // { - // if(cinf->pEngine->isCryptographicEngine() && (*(d->ptr()) == KVI_TEXT_CRYPT)) - // { - // KviCString decryptedStuff; - // if(cinf->pEngine->decrypt(d->ptr() + 1,decryptedStuff)) - // { - // m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSGCRYPTED, - // m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(), - // m_pDescriptor->szHost.ptr(),decryptedStuff.ptr()); - // } else { - // output(KVI_OUT_SYSTEMERROR, - // __tr("The following message looks like an encrypted one, but the crypting engine failed to decode it: %s"), - // cinf->pEngine->lastError()); - // m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG, - // m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(), - // m_pDescriptor->szHost.ptr(),d->ptr() + 1); - // } - // delete d; - // return true; - // } else { - // if(!(cinf->pEngine->isCryptographicEngine())) - // { - // KviCString decryptedStuff; - // if(cinf->pEngine->decrypt(d->ptr(),decryptedStuff)) - // { - // m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG, - // m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(), - // m_pDescriptor->szHost.ptr(),decryptedStuff.ptr()); - // delete d; - // return true; - // } else { - // output(KVI_OUT_SYSTEMERROR, - // __tr("The following message looks like an encrypted one, but the crypting engine failed to decode it: %s"), - // cinf->pEngine->lastError()); - // } - // } - // } - // } - // } - //#endif - // m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG, - // m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(), - // m_pDescriptor->szHost.ptr(),d->ptr()); - // } - // delete d; - // return true; - // } - // break; - // } - // } - return KviWindow::event(e); - } - - void KviDccCanvas::resizeEvent(QResizeEvent *e) - { - int hght = m_pInput->heightHint(); - // int hght2 = m_pTopSplitter->sizeHint().height(); - // m_pTopSplitter->setGeometry(0,0,width(),hght2); - m_pSplitter->setGeometry(0,0,width(),height() - hght); - m_pInput->setGeometry(0,height() - hght,width(),hght); - } - - QSize KviDccCanvas::sizeHint() const - { - QSize ret(m_pIrcView->sizeHint().width(), - m_pIrcView->sizeHint().height() + m_pInput->heightHint()); - return ret; - } - - void KviDccCanvas::handleMarshalError(int err) - { - QString sss = KviError::getDescription(err); - output(KVI_OUT_DCCERROR,__tr2qs_ctx("DCC Failed: %Q","dcc"),&sss); - } - - void KviDccCanvas::connected() - { - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Connected to %Q:%Q","dcc"), - &(m_pMarshal->remoteIp()),&(m_pMarshal->remotePort())); - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Local end is %Q:%Q","dcc"), - &(m_pMarshal->localIp()),&(m_pMarshal->localPort())); - if(!(m_pDescriptor->bActive)) - { - // PASSIVE CONNECTION...Find out the remote end - m_pDescriptor->szIp = m_pMarshal->remoteIp(); - m_pDescriptor->szPort = m_pMarshal->remotePort(); - m_pDescriptor->szHost = m_pMarshal->remoteIp(); - } - updateCaption(); - // m_pSlaveThread = new KviDccCanvasThread(this,m_pMarshal->releaseSocket()); - // m_pSlaveThread->start(); - } - - #include "m_canvas.moc" -#endif diff --git a/src/modules/dcc/canvas.h b/src/modules/dcc/canvas.h deleted file mode 100644 index 721cf7f00..000000000 --- a/src/modules/dcc/canvas.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef _CANVAS_H_ -#define _CANVAS_H_ -//============================================================================= -// -// File : canvas.h -// Creation date : Sun Jul 29 07 2001 20:17:12 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "broker.h" - -#ifdef COMPILE_DCC_CANVAS - #include "descriptor.h" - #include "window.h" - #include "thread.h" - - #include "KviWindow.h" - #include "KviCString.h" - #include "KviPointerList.h" - - class KviDccMarshal; - class KviCanvasWidget; - class QSplitter; - - class KviDccCanvas : public KviDccWindow - { - Q_OBJECT - public: - KviDccCanvas(KviMainWindow *pFrm,KviDccDescriptor * dcc,const char * name); - ~KviDccCanvas(); - protected: - // KviDccCanvasThread * m_pSlaveThread; - KviCanvasWidget * m_pCanvas; - // QSplitter * m_pTopSplitter; - QString m_szTarget; - protected: - virtual const QString &target(); - virtual void fillCaptionBuffers(); - virtual void getBaseLogFileName(KviCString &buffer); - virtual QPixmap * myIconPtr(); - virtual void resizeEvent(QResizeEvent *e); - virtual QSize sizeHint() const; - virtual bool event(QEvent *e); - virtual void ownMessage(const char *text, bool bUserFeedback = true); - virtual void ownAction(const char *text); - protected slots: - void handleMarshalError(int err); - void connected(); - }; -#endif - -#endif // _CANVAS_H_ diff --git a/src/modules/dcc/canvaswidget.cpp b/src/modules/dcc/canvaswidget.cpp index 765d78a1d..18cb9badd 100644 --- a/src/modules/dcc/canvaswidget.cpp +++ b/src/modules/dcc/canvaswidget.cpp @@ -457,7 +457,7 @@ // // KviCanvasView // - KviCanvasView::KviCanvasView(QCanvas * c,KviCanvasWidget * cw,QWidget * par) + KviCanvasView::KviCanvasView(QCanvas * c,DccCanvasWidget * cw,QWidget * par) : QCanvasView(c,par) { m_pCanvasWidget = cw; @@ -1451,9 +1451,9 @@ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // - // KviCanvasWidget + // DccCanvasWidget // - KviCanvasWidget::KviCanvasWidget(QWidget * par) + DccCanvasWidget::DccCanvasWidget(QWidget * par) : QWidget(par,"canvas_widget") { m_pCanvas = new QCanvas(this); @@ -1495,11 +1495,11 @@ m_pMenuBar->insertItem(__tr2qs_ctx("&Insert","dcc"),add); } - KviCanvasWidget::~KviCanvasWidget() + DccCanvasWidget::~DccCanvasWidget() { } - void KviCanvasWidget::resizeEvent(QResizeEvent *) + void DccCanvasWidget::resizeEvent(QResizeEvent *) { int h = m_pMenuBar->sizeHint().height(); m_pMenuBar->setGeometry(0,0,width(),h); diff --git a/src/modules/dcc/canvaswidget.h b/src/modules/dcc/canvaswidget.h index ac994bf28..41a14d628 100644 --- a/src/modules/dcc/canvaswidget.h +++ b/src/modules/dcc/canvaswidget.h @@ -24,7 +24,7 @@ // //============================================================================= -#include "broker.h" +#include "DccBroker.h" #ifdef COMPILE_DCC_CANVAS #include @@ -35,7 +35,7 @@ #include #include - class KviCanvasWidget; + class DccCanvasWidget; #define KVI_CANVAS_RTTI_CONTROL_TYPE_RECTANGLE 1 #define KVI_CANVAS_RTTI_CONTROL_TYPE_LINE 2 @@ -191,7 +191,7 @@ { Q_OBJECT public: - KviCanvasView(QCanvas * c,KviCanvasWidget * cw,QWidget * par); + KviCanvasView(QCanvas * c,DccCanvasWidget * cw,QWidget * par); ~KviCanvasView(); public: enum State { Idle, SelectOrigin }; @@ -205,7 +205,7 @@ LeftBottom, RightBottom, Scale, SinglePoint, Rotate }; protected: - KviCanvasWidget * m_pCanvasWidget; + DccCanvasWidget * m_pCanvasWidget; // Insertion of objects State m_state; @@ -280,13 +280,13 @@ }; - class KviCanvasWidget : public QWidget + class DccCanvasWidget : public QWidget { friend class KviCanvasView; Q_OBJECT public: - KviCanvasWidget(QWidget * par); - ~KviCanvasWidget(); + DccCanvasWidget(QWidget * par); + ~DccCanvasWidget(); protected: QSplitter * m_pSplitter; QCanvas * m_pCanvas; diff --git a/src/modules/dcc/chat.cpp b/src/modules/dcc/chat.cpp deleted file mode 100644 index f7dbf6048..000000000 --- a/src/modules/dcc/chat.cpp +++ /dev/null @@ -1,893 +0,0 @@ -//============================================================================= -// -// File : chat.cpp -// Creation date : Tue Sep 20 09 2000 15:13:13 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "chat.h" -#include "marshal.h" -#include "broker.h" - -#ifdef COMPILE_ON_WINDOWS - // Ugly Windoze compiler... - #include "dialogs.h" -#endif - -#include "kvi_debug.h" -#include "KviOptions.h" -#include "KviInput.h" -#include "KviIrcView.h" -#include "KviIconManager.h" -#include "KviLocale.h" -#include "kvi_out.h" -#include "KviNetUtils.h" -#include "KviConsoleWindow.h" -#include "KviMainWindow.h" -#include "KviMemory.h" -#include "KviMemory.h" -#include "KviThread.h" -#include "KviIrcSocket.h" -#include "kvi_settings.h" -#include "kvi_socket.h" -#include "KviApplication.h" -#include "KviParameterList.h" -#include "KviIrcConnection.h" -#include "KviIrcConnectionUserInfo.h" -#include "KviKvsEventTriggers.h" -#include "KviMircCntrl.h" -#include "KviTalVBox.h" - -#include -#include -#include -#include //for Qt::escape - -#ifdef COMPILE_CRYPT_SUPPORT - #include "KviCryptEngine.h" - #include "KviCryptController.h" -#endif - -#ifdef COMPILE_SSL_SUPPORT - #include "KviSSLMaster.h" -#endif - -extern KviDccBroker * g_pDccBroker; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -////// -////// WINDOW -////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -KviDccChat::KviDccChat(KviMainWindow *pFrm,KviDccDescriptor * dcc,const char * name) -: KviDccWindow(KVI_WINDOW_TYPE_DCCCHAT,pFrm,name,dcc) -{ - m_pButtonBox = new KviTalHBox(this); - - m_pLabel = new KviThemedLabel(m_pButtonBox, this, "dcc_chat_label"); - m_pLabel->setText(name); - m_pButtonBox->setStretchFactor(m_pLabel,1); - - m_pButtonContainer= new KviTalHBox(m_pButtonBox); - createTextEncodingButton(m_pButtonContainer); - -#ifdef COMPILE_CRYPT_SUPPORT - createCryptControllerButton(m_pButtonContainer); -#endif - - m_pSplitter = new KviTalSplitter(Qt::Horizontal,this); - m_pSplitter->setObjectName("dcc_chat_splitter"); - m_pSplitter->setChildrenCollapsible(false); - - m_pIrcView = new KviIrcView(m_pSplitter,pFrm,this); - connect(m_pIrcView,SIGNAL(rightClicked()),this,SLOT(textViewRightClicked())); - m_pInput = new KviInput(this); - - //setFocusHandler(m_pInput,this); - - m_pSlaveThread = 0; - - if(KVI_OPTION_BOOL(KviOption_boolAutoLogDccChat))m_pIrcView->startLogging(); - - m_pMarshal = new KviDccMarshal(this); - connect(m_pMarshal,SIGNAL(error(int)),this,SLOT(handleMarshalError(int))); - connect(m_pMarshal,SIGNAL(connected()),this,SLOT(connected())); - connect(m_pMarshal,SIGNAL(inProgress()),this,SLOT(connectionInProgress())); -#ifdef COMPILE_SSL_SUPPORT - connect(m_pMarshal,SIGNAL(startingSSLHandshake()),this,SLOT(startingSSLHandshake())); - connect(m_pMarshal,SIGNAL(sslError(const char *)),this,SLOT(sslError(const char *))); -#endif - - m_pSlaveThread = 0; - - startConnection(); -} - -KviDccChat::~KviDccChat() -{ - g_pDccBroker->unregisterDccWindow(this); - if(m_pSlaveThread) - { - m_pSlaveThread->terminate(); - delete m_pSlaveThread; - m_pSlaveThread = 0; - } - KviThreadManager::killPendingEvents(this); -} - -void KviDccChat::textViewRightClicked() -{ - KVS_TRIGGER_EVENT_1(KviEvent_OnDCCChatPopupRequest,this,m_pDescriptor->idString()); -} - -void KviDccChat::triggerCreationEvents() -{ - KVS_TRIGGER_EVENT_1(KviEvent_OnDCCChatWindowCreated,this,m_pDescriptor->idString()); -} - -void KviDccChat::triggerDestructionEvents() -{ - KVS_TRIGGER_EVENT_1(KviEvent_OnDCCChatWindowClosing,this,m_pDescriptor->idString()); -} - -void KviDccChat::startConnection() -{ - if(!(m_pDescriptor->bActive)) - { - // PASSIVE CONNECTION - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Attempting a passive DCC %s connection","dcc"),m_pDescriptor->szType.toUtf8().data()); -#ifdef COMPILE_SSL_SUPPORT - KviError::Code eError = m_pMarshal->dccListen(m_pDescriptor->szListenIp,m_pDescriptor->szListenPort,m_pDescriptor->bDoTimeout,m_pDescriptor->bIsSSL); -#else - KviError::Code eError = m_pMarshal->dccListen(m_pDescriptor->szListenIp,m_pDescriptor->szListenPort,m_pDescriptor->bDoTimeout); -#endif - if(eError != KviError::Success) - handleMarshalError(eError); - } else { - // ACTIVE CONNECTION - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Attempting an active DCC %s connection","dcc"),m_pDescriptor->szType.toUtf8().data()); -#ifdef COMPILE_SSL_SUPPORT - KviError::Code eError = m_pMarshal->dccConnect(m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data(),m_pDescriptor->bDoTimeout,m_pDescriptor->bIsSSL); -#else - KviError::Code eError = m_pMarshal->dccConnect(m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data(),m_pDescriptor->bDoTimeout); -#endif - if(eError != KviError::Success) - handleMarshalError(eError); - } -} - -void KviDccChat::connectionInProgress() -{ - if(m_pDescriptor->bActive) - { - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Contacting host %Q on port %Q","dcc"),&(m_pDescriptor->szIp),&(m_pDescriptor->szPort)); - } else { - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Listening on interface %Q port %Q","dcc"),&(m_pMarshal->localIp()),&(m_pMarshal->localPort())); - - if(m_pDescriptor->bSendRequest) - { - KviCString ip; - if(!m_pDescriptor->szFakeIp.isEmpty()) - { - ip = m_pDescriptor->szFakeIp; - } else { - ip = m_pDescriptor->szListenIp; - - if(KVI_OPTION_BOOL(KviOption_boolDccGuessIpFromServerWhenLocalIsUnroutable)) - { - if(!kvi_isRoutableIpString(ip.ptr())) - { - // try to get the IP that the IRC server can see - if(m_pDescriptor->console()) - { - KviCString tmp = m_pDescriptor->console()->connection() ? m_pDescriptor->console()->connection()->userInfo()->hostIp().toUtf8().data() : ""; - if(tmp.hasData()) - { - ip = tmp; - output(KVI_OUT_DCCMSG,__tr2qs_ctx("The local IP address is private, determining from IRC server: %s","dcc"),ip.ptr()); - } else { - output(KVI_OUT_DCCMSG,__tr2qs_ctx("The local IP address is private, but unable to determine it from the IRC server","dcc")); - } - } else { - output(KVI_OUT_DCCMSG,__tr2qs_ctx("The local IP address is private, but have no IRC server to determine it from","dcc")); - } - } - } - } - - QString port = !m_pDescriptor->szFakePort.isEmpty() ? m_pDescriptor->szFakePort : QString(m_pMarshal->localPort()); - - //FIXME: #warning "OPTION FOR SENDING 127.0.0.1 and so on (not an unsigned number)" - struct in_addr a; - if(KviNetUtils::stringIpToBinaryIp(ip.ptr(),&a))ip.setNum(htonl(a.s_addr)); - - QString szReq = QString("PRIVMSG %1 :%2DCC %3 chat %4 %5").arg(m_pDescriptor->szNick, QChar(0x01), m_pDescriptor->szType, ip.ptr(), port); - - if(m_pDescriptor->isZeroPortRequest()) - { - szReq.append(" "); - szReq+=m_pDescriptor->zeroPortRequestTag(); - } - szReq.append((char)(0x01)); - - m_pDescriptor->console()->connection()->sendData(m_pDescriptor->console()->connection()->encodeText(szReq).data()); - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Sent DCC %Q request to %Q, waiting for the remote client to connect...","dcc"), - &(m_pDescriptor->szType),&(m_pDescriptor->szNick)); - //qDebug(m_pDescriptor->szNick); - } else output(KVI_OUT_DCCMSG,__tr2qs_ctx("DCC %Q request not sent, awaiting manual connection","dcc"),&(m_pDescriptor->szType)); - } - KVS_TRIGGER_EVENT_1(KviEvent_OnDCCChatConnectionInProgress,this,m_pDescriptor->idString()); -} - -void KviDccChat::startingSSLHandshake() -{ -#ifdef COMPILE_SSL_SUPPORT - outputNoFmt(KVI_OUT_SSL,__tr2qs_ctx("Low-level transport connection established","dcc")); - outputNoFmt(KVI_OUT_SSL,__tr2qs_ctx("Starting Secure Socket Layer handshake","dcc")); -#endif -} - -void KviDccChat::sslError(const char * msg) -{ -#ifdef COMPILE_SSL_SUPPORT - if(!KVS_TRIGGER_EVENT_2_HALTED(KviEvent_OnDCCChatError,this,QString(msg),m_pDescriptor->idString())) - output(KVI_OUT_DCCERROR,__tr2qs_ctx("[SSL ERROR]: %s","dcc"),msg); -#endif -} - -const QString & KviDccChat::target() -{ - // This may change on the fly... - m_szTarget = m_pDescriptor->szNick; - m_szTarget += "@"; - m_szTarget += m_pDescriptor->szIp; - m_szTarget += ":"; - m_szTarget += m_pDescriptor->szPort; - return m_szTarget; -} - -void KviDccChat::fillCaptionBuffers() -{ - QString tmp = QString("DCC %1 %2@%3:%4").arg( -#ifdef COMPILE_SSL_SUPPORT - m_pDescriptor->bIsSSL ? "SChat" : "Chat", -#else - "Chat", -#endif - m_pDescriptor->szNick, m_pDescriptor->szIp, m_pDescriptor->szPort); - - m_szPlainTextCaption = tmp; -} - -QPixmap * KviDccChat::myIconPtr() -{ - return g_pIconManager->getSmallIcon(KVI_SMALLICON_DCCMSG); -} - -void KviDccChat::getBaseLogFileName(QString &buffer) -{ - buffer.sprintf("%s_%s_%s",m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data()); -} - -void KviDccChat::ownMessage(const QString &text, bool bUserFeedback) -{ - if(!m_pSlaveThread) - { - output(KVI_OUT_SYSTEMWARNING,__tr2qs_ctx("Cannot send data: No active connection","dcc")); - return; - } - - QByteArray szData = encodeText(text); - const char * d = szData.data(); - if(!d)return; - -#ifdef COMPILE_CRYPT_SUPPORT - if(cryptSessionInfo()) - { - if(cryptSessionInfo()->m_bDoEncrypt) - { - if(*d != KviMircCntrl::CryptEscape) - { - KviCString encrypted; - cryptSessionInfo()->m_pEngine->setMaxEncryptLen(-1); - switch(cryptSessionInfo()->m_pEngine->encrypt(d,encrypted)) - { - case KviCryptEngine::Encrypted: - { - KviCString buf(KviCString::Format,"%s\r\n",encrypted.ptr()); - m_pSlaveThread->sendRawData(buf.ptr(),buf.len()); - if(bUserFeedback) - m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSGCRYPTED, - m_pDescriptor->szLocalNick.toUtf8().data(),m_pDescriptor->szLocalUser.toUtf8().data(), - m_pDescriptor->szLocalHost.toUtf8().data(),text,KviConsoleWindow::NoNotifications); - } - break; - case KviCryptEngine::Encoded: - { - KviCString buf(KviCString::Format,"%s\r\n",encrypted.ptr()); - m_pSlaveThread->sendRawData(buf.ptr(),buf.len()); - if(bUserFeedback) - { - QString encr = decodeText(encrypted.ptr()); - m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG, - m_pDescriptor->szLocalNick.toUtf8().data(),m_pDescriptor->szLocalUser.toUtf8().data(), - m_pDescriptor->szLocalHost.toUtf8().data(),encr,KviConsoleWindow::NoNotifications); - } - } - break; - default: // also case KviCryptEngine::EncryptError - { - QString szErr = cryptSessionInfo()->m_pEngine->lastError(); - output(KVI_OUT_SYSTEMERROR, - __tr2qs_ctx("The crypto engine was not able to encrypt the current message (%Q): %Q, no data was sent to the remote end","dcc"), - &text,&szErr); - } - break; - } - return; - } else { - d++; //eat the escape code - KviCString buf(KviCString::Format,"%s\r\n",d); - QString tmp = text.right(text.length() - 1); - m_pSlaveThread->sendRawData(buf.ptr(),buf.len()); - - if(bUserFeedback) - m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG, - m_pDescriptor->szLocalNick.toUtf8().data(),m_pDescriptor->szLocalUser.toUtf8().data(), - m_pDescriptor->szLocalHost.toUtf8().data(),tmp,KviConsoleWindow::NoNotifications); - return; - } - } - } -#endif - KviCString buf(KviCString::Format,"%s\r\n",d); - m_pSlaveThread->sendRawData(buf.ptr(),buf.len()); - - if(bUserFeedback) - m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG, - m_pDescriptor->szLocalNick.toUtf8().data(),m_pDescriptor->szLocalUser.toUtf8().data(), - m_pDescriptor->szLocalHost.toUtf8().data(),text,KviConsoleWindow::NoNotifications); -} - -const QString & KviDccChat::localNick() -{ - // FIXME: This is just a complete HACK - m_szLocalNick = m_pDescriptor->szLocalNick; - return m_szLocalNick; -} - -void KviDccChat::ownAction(const QString &text) -{ - if(m_pSlaveThread) - { - QString szTmpBuffer; - //see bug ticket #220 - if(KVI_OPTION_BOOL(KviOption_boolStripMircColorsInUserMessages)) - { - szTmpBuffer = KviMircCntrl::stripControlBytes(text); - } else { - szTmpBuffer = text; - } - - QByteArray szData = encodeText(szTmpBuffer); - const char * d = szData.data(); - if(!d) - return; - KviCString buf(KviCString::Format,"%cACTION %s%c\r\n",0x01,d,0x01); - m_pSlaveThread->sendRawData(buf.ptr(),buf.len()); - output(KVI_OUT_ACTION,"%Q %Q",&(m_pDescriptor->szLocalNick),&szTmpBuffer); - } else { - output(KVI_OUT_SYSTEMWARNING,__tr2qs_ctx("Cannot send data: No active connection","dcc")); - } -} - -bool KviDccChat::event(QEvent *e) -{ - if(e->type() == KVI_THREAD_EVENT) - { - switch(((KviThreadEvent *)e)->id()) - { - case KVI_DCC_THREAD_EVENT_ERROR: - { - KviError::Code * pError = ((KviThreadDataEvent *)e)->getData(); - QString szErr = KviError::getDescription(*pError); - if(!KVS_TRIGGER_EVENT_2_HALTED(KviEvent_OnDCCChatError,this,szErr,m_pDescriptor->idString())) - output(KVI_OUT_DCCERROR,__tr2qs_ctx("ERROR: %Q","dcc"),&szErr); - KVS_TRIGGER_EVENT_1(KviEvent_OnDCCChatDisconnected,this,m_pDescriptor->idString()); - delete pError; - return true; - } - break; - case KVI_DCC_THREAD_EVENT_DATA: - { - KviCString * encoded = ((KviThreadDataEvent *)e)->getData(); - KviCString d=KviCString(decodeText(encoded->ptr())); - if(d.firstCharIs(0x01)) - { - d.cutLeft(1); - if(d.lastCharIs(0x01))d.cutRight(1); - if(kvi_strEqualCIN("ACTION",d.ptr(),6))d.cutLeft(6); - d.stripLeftWhiteSpace(); - output(KVI_OUT_ACTION,"%Q %s",&(m_pDescriptor->szNick),d.ptr()); - if(!hasAttention()) - { - if(KVI_OPTION_BOOL(KviOption_boolFlashDccChatWindowOnNewMessages)) - { - demandAttention(); - } - if(KVI_OPTION_BOOL(KviOption_boolPopupNotifierOnNewDccChatMessages)) - { - QString szMsg = ""; - szMsg += m_pDescriptor->szNick; - szMsg += " "; - szMsg += Qt::escape(QString(d.ptr())); - //qDebug("KviIrcServerParser_ctcp.cpp:975 debug: %s",szMsg.data()); - g_pApp->notifierMessage(this,KVI_OPTION_MSGTYPE(KVI_OUT_ACTION).pixId(),szMsg,KVI_OPTION_UINT(KviOption_uintNotifierAutoHideTime)); - } - } - } else { - -#ifdef COMPILE_CRYPT_SUPPORT - if(KviCryptSessionInfo * cinf = cryptSessionInfo()) - { - if(cinf->m_bDoDecrypt) - { - KviCString decryptedStuff; - switch(cinf->m_pEngine->decrypt(d.ptr(),decryptedStuff)) - { - case KviCryptEngine::DecryptOkWasEncrypted: - case KviCryptEngine::DecryptOkWasEncoded: - case KviCryptEngine::DecryptOkWasPlainText: - if(!KVS_TRIGGER_EVENT_2_HALTED(KviEvent_OnDCCChatMessage,this,QString(decryptedStuff.ptr()),m_pDescriptor->idString())) - { - m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG, - m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szUser.toUtf8().data(), - m_pDescriptor->szHost.toUtf8().data(),decryptedStuff.ptr()); - } - delete encoded; - return true; - break; - - default: // also case KviCryptEngine::DecryptError - { - QString szErr = cinf->m_pEngine->lastError(); - output(KVI_OUT_SYSTEMERROR, - __tr2qs_ctx("The following message appears to be encrypted, but the crypto engine failed to decode it: %Q","dcc"), - &szErr); - } - break; - } - } - } else { -#endif - // FIXME! - if(!KVS_TRIGGER_EVENT_2_HALTED(KviEvent_OnDCCChatMessage,this,QString(d.ptr()),m_pDescriptor->idString())) - { - m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG, - m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szUser.toUtf8().data(), - m_pDescriptor->szHost.toUtf8().data(),d.ptr()); - if(!hasAttention()) - { - if(KVI_OPTION_BOOL(KviOption_boolFlashDccChatWindowOnNewMessages)) - { - demandAttention(); - } - if(KVI_OPTION_BOOL(KviOption_boolPopupNotifierOnNewDccChatMessages)) - { - QString szMsg = Qt::escape(QString(d.ptr())); - g_pApp->notifierMessage(this,KVI_SMALLICON_DCCCHATMSG,szMsg,KVI_OPTION_UINT(KviOption_uintNotifierAutoHideTime)); - } - } - } -#ifdef COMPILE_CRYPT_SUPPORT - } -#endif - } - delete encoded; - return true; - } - break; - } - } - return KviWindow::event(e); -} - -void KviDccChat::resizeEvent(QResizeEvent *) -{ - int hght = m_pInput->heightHint(); - int hght2 = m_pButtonBox->sizeHint().height(); - m_pButtonBox->setGeometry(0,0,width(),hght2); - m_pSplitter->setGeometry(0,hght2,width(),height() - (hght + hght2)); - m_pInput->setGeometry(0,height() - hght,width(),hght); -} - -QSize KviDccChat::sizeHint() const -{ - QSize ret(m_pIrcView->sizeHint().width(), - m_pIrcView->sizeHint().height() + m_pInput->heightHint()); - return ret; -} - -void KviDccChat::handleMarshalError(KviError::Code eError) -{ - QString szErr = KviError::getDescription(eError); - if(!KVS_TRIGGER_EVENT_2_HALTED(KviEvent_OnDCCChatError,this,szErr,m_pDescriptor->idString())) - output(KVI_OUT_DCCERROR,__tr2qs_ctx("DCC %Q failed: %Q","dcc"),&(m_pDescriptor->szType),&szErr); -} - -void KviDccChat::connected() -{ - if(!(m_pDescriptor->bActive)) - { - // PASSIVE CONNECTION...Find out the remote end - m_pDescriptor->szIp = m_pMarshal->remoteIp(); - m_pDescriptor->szPort = m_pMarshal->remotePort(); - m_pDescriptor->szHost = m_pMarshal->remoteIp(); - } - - updateCaption(); - - m_pSlaveThread = new KviDccChatThread(this,m_pMarshal->releaseSocket()); - -#ifdef COMPILE_SSL_SUPPORT - KviSSL * s = m_pMarshal->releaseSSL(); - if(s) - { - KviSSLMaster::printSSLConnectionInfo(this,s); - m_pSlaveThread->setSSL(s); - } -#endif - m_pSlaveThread->start(); - - if(!KVS_TRIGGER_EVENT_1_HALTED(KviEvent_OnDCCChatConnected,this,m_pDescriptor->idString())) - { - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Connected to %Q:%Q","dcc"), - &(m_pMarshal->remoteIp()),&(m_pMarshal->remotePort())); - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Local end is %Q:%Q","dcc"), - &(m_pMarshal->localIp()),&(m_pMarshal->localPort())); -#ifdef COMPILE_SSL_SUPPORT - QString tmp = QString("dcc: %1 %2@%3:%4").arg(m_pDescriptor->bIsSSL ? "SChat" : "Chat", m_pDescriptor->szNick, m_pDescriptor->szIp, m_pDescriptor->szPort); -#else - QString tmp = QString("dcc: %1 %2@%3:%4").arg("Chat", m_pDescriptor->szNick, m_pDescriptor->szIp, m_pDescriptor->szPort); -#endif - m_pLabel->setText(tmp); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -////// -////// THREAD -////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - -KviDccChatThread::KviDccChatThread(KviWindow *wnd,kvi_socket_t fd) -: KviDccThread(wnd,fd) -{ - m_pOutBuffers = new KviPointerList; - m_pOutBuffers->setAutoDelete(true); -} - -KviDccChatThread::~KviDccChatThread() -{ - if(m_pOutBuffers)delete m_pOutBuffers; -} - -void KviDccChatThread::run() -{ - KviDccThreadIncomingData data; - data.iLen = 0; - data.buffer = 0; - - for(;;) - { - // Dequeue events - while(KviThreadEvent * e = dequeueEvent()) - { - if(e->id() == KVI_THREAD_EVENT_TERMINATE) - { - delete e; - goto out_of_the_loop; - } else { - // Other events are senseless to us - delete e; - } - } - - bool bCanRead; - bool bCanWrite; - if(kvi_select(m_fd,&bCanRead,&bCanWrite)) - { - if(bCanWrite) - { - if(!tryFlushOutBuffers())goto out_of_the_loop; - } - if(bCanRead) - { - data.buffer = (char *) KviMemory::reallocate(data.buffer,(data.iLen + 512) * sizeof(char)); - int readLen; -#ifdef COMPILE_SSL_SUPPORT - if(m_pSSL) - { - readLen = m_pSSL->read(data.buffer + data.iLen,512); - } else { -#endif - readLen = kvi_socket_recv(m_fd,data.buffer + data.iLen,512); -#ifdef COMPILE_SSL_SUPPORT - } -#endif - if(readLen > 0) - { - data.iLen += readLen; - data.buffer = (char *)KviMemory::reallocate(data.buffer,data.iLen * sizeof(char)); - if(!handleIncomingData(&data,false))break; // non critical... - } else { - -#ifdef COMPILE_SSL_SUPPORT - if(m_pSSL) - { - // ssl error....? - switch(m_pSSL->getProtocolError(readLen)) - { - case KviSSL::ZeroReturn: - readLen = 0; - break; - case KviSSL::WantRead: - case KviSSL::WantWrite: - // hmmm... - break; - case KviSSL::SyscallError: - { - int iE = m_pSSL->getLastError(true); - if(iE != 0) - { - raiseSSLError(); - postErrorEvent(KviError::SSLError); - goto out_of_the_loop; - } - } - break; - case KviSSL::SSLError: - { - raiseSSLError(); - postErrorEvent(KviError::SSLError); - goto out_of_the_loop; - } - break; - default: - // Raise unknown SSL ERROR - postErrorEvent(KviError::SSLError); - goto out_of_the_loop; - break; - } - } -#endif - if(data.iLen > 0) - { - data.buffer = (char *)KviMemory::reallocate(data.buffer,data.iLen * sizeof(char)); - } else { - KviMemory::free(data.buffer); - data.buffer = 0; - } - - if(!handleInvalidSocketRead(readLen)) - { - if(data.iLen)handleIncomingData(&data,true); // critical - KVI_ASSERT(!data.iLen); - break; // error - } - } - } - msleep(100); - } - } - -out_of_the_loop: - - - if(data.iLen)KviMemory::free(data.buffer); - -#ifdef COMPILE_SSL_SUPPORT - if(m_pSSL) - { - KviSSLMaster::freeSSL(m_pSSL); - m_pSSL = 0; - } -#endif - - if(m_fd != KVI_INVALID_SOCKET)::kvi_socket_close(m_fd); - m_fd = KVI_INVALID_SOCKET; -} - -bool KviDccChatThread::handleIncomingData(KviDccThreadIncomingData * data,bool bCritical) -{ - KVI_ASSERT(data->iLen); - KVI_ASSERT(data->buffer); - char * aux = data->buffer; - char * end = data->buffer + data->iLen; - while(aux != end) - { - if((*aux == '\n') || (*aux == '\0')) - { - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_DATA); - // The left part is len chars long - int len = aux - data->buffer; -// qDebug("LEN = %d, iLen = %d",len,data->iLen); -//#warning "DO IT BETTER (the \r cutting)" - KviCString * s = new KviCString(data->buffer,len); - if(s->lastCharIs('\r'))s->cutRight(1); - e->setData(s); - // but we cut also \n (or \0) - ++aux; - // so len += 1; --> new data->iLen -= len; - data->iLen -= (len + 1); -// qDebug("iLen now = %d",data->iLen); - KVI_ASSERT(data->iLen >= 0); - if(data->iLen > 0) - { - // memmove the remaining part to the beginning - // aux points after \n or \0 - KviMemory::move(data->buffer,aux,data->iLen); - data->buffer = (char *)KviMemory::reallocate(data->buffer,data->iLen); - end = data->buffer + data->iLen; - aux = data->buffer; - } else { - // no more data in the buffer - KVI_ASSERT(data->iLen == 0); - KviMemory::free(data->buffer); - data->buffer = end = aux = 0; - } - postEvent(parent(),e); - } else aux++; -// qDebug("PASSING CHAR %c",*aux); - } - // now aux == end - if(bCritical) - { - // need to flush everything... - if(data->iLen > 0) - { - // in the last part there are no NULL and \n chars - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_DATA); - KviCString * s = new KviCString(data->buffer,data->iLen); - if(s->lastCharIs('\r'))s->cutRight(1); - e->setData(s); - data->iLen = 0; - KviMemory::free(data->buffer); - data->buffer = 0; - postEvent(parent(),e); - } - } - return true; -} - -void KviDccChatThread::sendRawData(const void * buffer,int len) -{ - m_pMutex->lock(); - m_pOutBuffers->append(new KviDataBuffer((unsigned int)len,(const unsigned char *)buffer)); - m_pMutex->unlock(); -} - -bool KviDccChatThread::tryFlushOutBuffers() -{ - bool bRet = true; - m_pMutex->lock(); - while(KviDataBuffer * b = m_pOutBuffers->first()) - { - int sentLen; -#ifdef COMPILE_SSL_SUPPORT - if(m_pSSL) - { - sentLen = m_pSSL->write((const char *)b->data(),b->size()); - } else { -#endif - sentLen = kvi_socket_send(m_fd,b->data(),b->size()); -#ifdef COMPILE_SSL_SUPPORT - } -#endif - if(sentLen > 0) - { - if(sentLen == b->size())m_pOutBuffers->removeFirst(); - else { - // just a part - b->remove((unsigned int)sentLen); - break; - } - } else { -#ifdef COMPILE_SSL_SUPPORT - if(m_pSSL) - { - // ops...might be an SSL error - switch(m_pSSL->getProtocolError(sentLen)) - { - case KviSSL::WantWrite: - case KviSSL::WantRead: - // Async continue... - goto handle_system_error; - break; - case KviSSL::SyscallError: - if(sentLen == 0) - { - raiseSSLError(); - postErrorEvent(KviError::RemoteEndClosedConnection); - bRet = false; - goto out_of_the_loop; - } else { - int iSSLErr = m_pSSL->getLastError(true); - if(iSSLErr != 0) - { - raiseSSLError(); - postErrorEvent(KviError::SSLError); - bRet = false; - goto out_of_the_loop; - } else { - goto handle_system_error; - } - } - break; - case KviSSL::SSLError: - raiseSSLError(); - postErrorEvent(KviError::SSLError); - bRet = false; - goto out_of_the_loop; - break; - default: - postErrorEvent(KviError::SSLError); - bRet = false; - goto out_of_the_loop; - break; - } - } -#endif -handle_system_error: - if(sentLen < 0) - { - int err = kvi_socket_error(); -#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - if((err != EAGAIN) || (err != EINTR) || (err != WSAEWOULDBLOCK)) -#else - if((err != EAGAIN)||(err != EINTR)) -#endif - { - postErrorEvent(KviError::translateSystemError(err)); - bRet = false; - goto out_of_the_loop; - } - } - break; // send error - } - } -out_of_the_loop: - m_pMutex->unlock(); - return bRet; -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_chat.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/dcc/chat.h b/src/modules/dcc/chat.h deleted file mode 100644 index dddf0a6ba..000000000 --- a/src/modules/dcc/chat.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef _CHAT_H_ -#define _CHAT_H_ -//============================================================================= -// -// File : chat.h -// Creation date : Tue Sep 20 09 2000 15:11:12 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "descriptor.h" -#include "thread.h" -#include "window.h" - -#include "KviDataBuffer.h" -#include "KviPointerList.h" -#include "KviThemedLabel.h" -#include "KviCString.h" -#include "KviWindow.h" -#include "KviError.h" - -#ifdef COMPILE_SSL_SUPPORT - class KviSSL; -#endif - -class KviDccMarshal; -class QSplitter; - -class KviDccChatThread : public KviDccThread -{ -public: - KviDccChatThread(KviWindow * wnd,kvi_socket_t fd); - ~KviDccChatThread(); -protected: - KviPointerList * m_pOutBuffers; -protected: - virtual void run(); - bool tryFlushOutBuffers(); - // This should handle the incoming data buffer - // must "eat" some data from data.buffer, memmove the remaining part - // to the beginning, kvi_realloc data.buffer and update data.iLen - // If bCritical is true, it should handle the whole data buffer - // since the thread is going to die - // It should return true if the handing was succesfull - // or false if the thread should be stopped - virtual bool handleIncomingData(KviDccThreadIncomingData *data,bool bCritical); -public: - virtual void sendRawData(const void * buffer,int len); // mutex (m_pOutBuffers usage) -}; - - -class KviDccChat : public KviDccWindow -{ - Q_OBJECT -public: - KviDccChat(KviMainWindow *pFrm,KviDccDescriptor * dcc,const char * name); - ~KviDccChat(); - QFrame * buttonContainer() { return (QFrame*)m_pButtonContainer; }; -protected: - KviDccChatThread * m_pSlaveThread; - QString m_szTarget; - QString m_szLocalNick; - KviThemedLabel * m_pLabel; - KviTalHBox * m_pButtonBox; - KviTalHBox * m_pButtonContainer; -protected: - virtual const QString & target(); - virtual void fillCaptionBuffers(); - virtual void getBaseLogFileName(QString &buffer); - virtual QPixmap * myIconPtr(); - virtual void resizeEvent(QResizeEvent *e); - virtual QSize sizeHint() const; - virtual const QString & localNick(); - virtual bool event(QEvent *e); - virtual void ownMessage(const QString &text, bool bUserFeedback = true); - virtual void ownAction(const QString &text); - virtual void triggerCreationEvents(); - virtual void triggerDestructionEvents(); - void startConnection(); - virtual KviDccThread * getSlaveThread() { return m_pSlaveThread; }; -protected slots: - void handleMarshalError(KviError::Code eError); - void connected(); - void sslError(const char * msg); - void connectionInProgress(); - void startingSSLHandshake(); - void textViewRightClicked(); -}; - -#endif //_CHAT_H_ diff --git a/src/modules/dcc/codec.cpp b/src/modules/dcc/codec.cpp deleted file mode 100644 index 39ab5d98b..000000000 --- a/src/modules/dcc/codec.cpp +++ /dev/null @@ -1,327 +0,0 @@ -//============================================================================= -// -// File : codec.cpp -// Creation date : Sun Aug 26 04:19:36 2001 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "codec.h" - - -#include -#include -#include - -KviDccVoiceCodec::KviDccVoiceCodec() -{ -} - -KviDccVoiceCodec::~KviDccVoiceCodec() -{ -} - -void KviDccVoiceCodec::encode(KviDataBuffer *,KviDataBuffer *) -{ -} - -void KviDccVoiceCodec::decode(KviDataBuffer *,KviDataBuffer *) -{ -} - -int KviDccVoiceCodec::encodedFrameSize() -{ - return 0; -} - -int KviDccVoiceCodec::decodedFrameSize() -{ - return 0; -} - -const char * KviDccVoiceCodec::name() -{ - return m_szName.ptr(); -} - -KviDccVoiceNullCodec::KviDccVoiceNullCodec() -: KviDccVoiceCodec() -{ - m_szName = "null (no compression)"; -} - -KviDccVoiceNullCodec::~KviDccVoiceNullCodec() -{ -} - -void KviDccVoiceNullCodec::encode(KviDataBuffer * signal,KviDataBuffer * stream) -{ - if(signal->size() < 1)return; - stream->append(signal->data(),signal->size()); - signal->resize(0); -} - -void KviDccVoiceNullCodec::decode(KviDataBuffer * stream,KviDataBuffer * signal) -{ - if(stream->size() < 1)return; - signal->append(stream->data(),stream->size()); - - stream->resize(0); -} - -int KviDccVoiceNullCodec::encodedFrameSize() -{ - return 1024; -} - -int KviDccVoiceNullCodec::decodedFrameSize() -{ - return 1024; -} - -//-------------------------- - -KviDccVideoCodec::KviDccVideoCodec() -{ -} - -KviDccVideoCodec::~KviDccVideoCodec() -{ -} - -void KviDccVideoCodec::encodeVideo(KviDataBuffer *,KviDataBuffer *) -{ -} - -void KviDccVideoCodec::encodeText(KviDataBuffer *,KviDataBuffer *) -{ -} - -void KviDccVideoCodec::decode(KviDataBuffer *,KviDataBuffer *,KviDataBuffer *) -{ -} - -int KviDccVideoCodec::encodedFrameSize() -{ - return 0; -} - -int KviDccVideoCodec::decodedFrameSize() -{ - return 0; -} - -const char * KviDccVideoCodec::name() -{ - return m_szName.ptr(); -} - -KviDccVideoSJpegCodec::KviDccVideoSJpegCodec() -: KviDccVideoCodec() -{ - m_szName = "sjpeg"; -} - -KviDccVideoSJpegCodec::~KviDccVideoSJpegCodec() -{ -} - -void KviDccVideoSJpegCodec::encodeVideo(KviDataBuffer * videoSignal,KviDataBuffer * stream) -{ - - if(videoSignal->size() < 1) return; - - QImage img(videoSignal->data(), 320, 240, 1280, QImage::Format_ARGB32); - QByteArray ba; - QBuffer buffer(&ba); - buffer.open(QIODevice::WriteOnly); - //0 to obtain small compressed files, - //100 for large uncompressed files, - //and -1 (the default) to use the default settings. - img.save(&buffer, "JPEG", 20); - if(ba.size() > 0) - { - stream->append((const unsigned char*)ba.data(),ba.size()); - } - videoSignal->clear(); -} - -void KviDccVideoSJpegCodec::encodeText(KviDataBuffer * textSignal, KviDataBuffer * stream) -{ - static unsigned const char *irct_magic_init = (unsigned const char*) "\0\0"; - static unsigned const char *irct_magic_end = (unsigned const char*) "\0\0"; - - qDebug("encodeText %s %d",textSignal->data(), textSignal->size()); - if(textSignal->size() < 1) return; - stream->append(irct_magic_init,8); - stream->append((const unsigned char*)textSignal->data(),textSignal->size()); - stream->append(irct_magic_end,9); - textSignal->clear(); - return; -} - -void KviDccVideoSJpegCodec::decode(KviDataBuffer * stream,KviDataBuffer * videoSignal,KviDataBuffer * textSignal) -{ - static unsigned const char jpg_magic_init[4] = { 0xFF, 0xD8, 0xFF, 0xE0}; //SOI + APP0 - static unsigned const char jpg_magic_end[2] = { 0xFF, 0xD9}; //EOI - - static unsigned const char *irct_magic_init = (unsigned const char*) "\0\0"; - static unsigned const char *irct_magic_end = (unsigned const char*) "\0\0"; - - if(stream->size() < 1)return; - - - int txtStart = stream->find(irct_magic_init, 8); - int txtEnd = stream->find(irct_magic_end, 9); - - int jpgStart = stream->find(jpg_magic_init, 4); - - if(txtStart!=-1 && txtEnd !=-1 && txtStartremove(txtStart+8); - int len = txtEnd - txtStart -8; //-8 irct_magic_init - if(len>0) - { - textSignal->append(stream->data(), len); - char*txt=(char*)malloc(len+1); - memcpy(txt,stream->data(), len); - txt[len]='\0'; - qDebug("a recv |%s| %d",txt,len); - } - stream->remove(len+9); - } - - if(stream->size() < 1)return; - - jpgStart = stream->find(jpg_magic_init, 4); - int jpgEnd = stream->find(jpg_magic_end, 2); - - if(jpgStart != -1 && jpgEnd != -1) - { -// qDebug("jpgStart %d jpgEnd %d",jpgStart,jpgEnd); - QImage img; - //remove junk before jpeg start - if(jpgStart > 0) - stream->remove(jpgStart); - - int len = jpgEnd - jpgStart + 1; - - img.loadFromData(stream->data(), stream->size()); - if(!img.isNull()) - { - videoSignal->clear(); - videoSignal->append(img.bits(),img.numBytes()); - } - stream->remove(len); - } - - txtStart = stream->find(irct_magic_init, 8); - txtEnd = stream->find(irct_magic_end, 9); - - if(txtStart!=-1 && txtEnd !=-1) - { - qDebug("b txtStart %d txtEnd %d",txtStart,txtEnd); - stream->remove(txtStart+8); - int len = txtEnd - txtStart -8; //-8 irct_magic_init - if(len>0) - { - textSignal->append(stream->data(), len); - char*txt=(char*)malloc(len+1); - memcpy(txt,stream->data(), len); - txt[len]='\0'; - qDebug("b recv |%s| %d",txt,len); - } - stream->remove(len+9); - } -} - -int KviDccVideoSJpegCodec::encodedFrameSize() -{ - return 0; -} - -int KviDccVideoSJpegCodec::decodedFrameSize() -{ - return 0; -} - - -#ifndef COMPILE_DISABLE_OGG_THEORA -KviDccVideoTheoraCodec::KviDccVideoTheoraCodec() -: KviDccVideoCodec() -{ - m_szName = "theora"; - m_pEncoder = 0; - m_pDecoder = 0; -} - -KviDccVideoTheoraCodec::~KviDccVideoTheoraCodec() -{ - if(m_pEncoder) - delete m_pEncoder; - m_pEncoder=0; - - if(m_pDecoder) - delete m_pDecoder; - m_pDecoder=0; -} - -void KviDccVideoTheoraCodec::encodeVideo(KviDataBuffer * videoSignal,KviDataBuffer * stream) -{ - if(videoSignal->size() < 1) return; - - if(!m_pEncoder) - m_pEncoder = new KviOggTheoraEncoder(stream); - - m_pEncoder->addVideoFrame((QRgb *) videoSignal->data(),videoSignal->size()); - videoSignal->clear(); -} - -void KviDccVideoTheoraCodec::encodeText(KviDataBuffer * textSignal, KviDataBuffer * stream) -{ - if(textSignal->size() < 1) return; - - if(!m_pEncoder) - m_pEncoder = new KviOggTheoraEncoder(stream); - - m_pEncoder->addTextFrame(textSignal->data(),textSignal->size()); - textSignal->clear(); -} - -void KviDccVideoTheoraCodec::decode(KviDataBuffer * stream,KviDataBuffer * videoSignal,KviDataBuffer * textSignal) -{ - if(stream->size() < 1)return; - - if(!m_pDecoder) - m_pDecoder = new KviOggTheoraDecoder(videoSignal, textSignal); - - m_pDecoder->addData(stream); -} - -int KviDccVideoTheoraCodec::encodedFrameSize() -{ - return 0; -} - -int KviDccVideoTheoraCodec::decodedFrameSize() -{ - return 0; -} -#endif // COMPILE_DISABLE_OGG_THEORA diff --git a/src/modules/dcc/codec.h b/src/modules/dcc/codec.h deleted file mode 100644 index 16897304c..000000000 --- a/src/modules/dcc/codec.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef _CODEC_H_ -#define _CODEC_H_ -//============================================================================= -// -// File : codec.h -// Creation date : Sun Aug 26 04:19:34 2001 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "KviCString.h" -#include "KviDataBuffer.h" - -#ifndef COMPILE_DISABLE_OGG_THEORA - #include "KviOggTheoraDecoder.h" - #include "KviOggTheoraEncoder.h" -#endif - -class KviDccVoiceCodec -{ -public: - KviDccVoiceCodec(); - virtual ~KviDccVoiceCodec(); -protected: - KviCString m_szName; -public: - const char * name(); - virtual void encode(KviDataBuffer * signal,KviDataBuffer * stream); - virtual void decode(KviDataBuffer * stream,KviDataBuffer * signal); - virtual int encodedFrameSize(); - virtual int decodedFrameSize(); -}; - -class KviDccVoiceNullCodec : public KviDccVoiceCodec -{ -public: - KviDccVoiceNullCodec(); - virtual ~KviDccVoiceNullCodec(); -public: - virtual void encode(KviDataBuffer * signal,KviDataBuffer * stream); - virtual void decode(KviDataBuffer * stream,KviDataBuffer * signal); - virtual int encodedFrameSize(); - virtual int decodedFrameSize(); -}; - -class KviDccVideoCodec -{ -public: - KviDccVideoCodec(); - virtual ~KviDccVideoCodec(); -protected: - KviCString m_szName; -public: - const char * name(); - virtual void encodeVideo(KviDataBuffer * videoSignal, KviDataBuffer * stream); - virtual void encodeText(KviDataBuffer * textSignal, KviDataBuffer * stream); - virtual void decode(KviDataBuffer * stream,KviDataBuffer * videoSignal,KviDataBuffer * textSignal); - virtual int encodedFrameSize(); - virtual int decodedFrameSize(); -}; - -class KviDccVideoSJpegCodec : public KviDccVideoCodec -{ -public: - KviDccVideoSJpegCodec(); - virtual ~KviDccVideoSJpegCodec(); -public: - virtual void encodeVideo(KviDataBuffer * videoSignal, KviDataBuffer * stream); - virtual void encodeText(KviDataBuffer * textSignal, KviDataBuffer * stream); - virtual void decode(KviDataBuffer * stream,KviDataBuffer * videoSignal,KviDataBuffer * textSignal); - virtual int encodedFrameSize(); - virtual int decodedFrameSize(); -}; - -#ifndef COMPILE_DISABLE_OGG_THEORA -class KviDccVideoTheoraCodec : public KviDccVideoCodec -{ -public: - KviDccVideoTheoraCodec(); - virtual ~KviDccVideoTheoraCodec(); -public: - virtual void encodeVideo(KviDataBuffer * videoSignal, KviDataBuffer * stream); - virtual void encodeText(KviDataBuffer * textSignal, KviDataBuffer * stream); - virtual void decode(KviDataBuffer * stream,KviDataBuffer * videoSignal,KviDataBuffer * textSignal); - virtual int encodedFrameSize(); - virtual int decodedFrameSize(); -private: - KviOggTheoraEncoder * m_pEncoder; - KviOggTheoraDecoder * m_pDecoder; -}; -#endif // COMPILE_DISABLE_OGG_THEORA -#endif //_CODEC_H_ diff --git a/src/modules/dcc/descriptor.cpp b/src/modules/dcc/descriptor.cpp deleted file mode 100644 index ba0f7270a..000000000 --- a/src/modules/dcc/descriptor.cpp +++ /dev/null @@ -1,231 +0,0 @@ -//============================================================================= -// -// File : descriptor.cpp -// Creation date : Tue Jul 23 01:11:54 2002 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "descriptor.h" -#include "send.h" -#include "window.h" - -#include "KviLocale.h" -#include "KviKvsEventTriggers.h" -#include "KviWindow.h" -#include "KviApplication.h" - -static unsigned int g_uNextDescriptorId = 1; // we use 0 as an invalid descriptor id -static KviPointerHashTable * g_pDescriptorDict = 0; - -KviPointerHashTable * KviDccDescriptor::descriptorDict() -{ - return g_pDescriptorDict; -} - -KviDccDescriptor::KviDccDescriptor(const KviDccDescriptor & src) -{ - copyFrom(src); -} - -KviDccDescriptor::KviDccDescriptor(KviConsoleWindow * pConsole) -{ - m_pConsole = pConsole; - m_pDccWindow = 0; - m_pDccTransfer = 0; - - m_uId = g_uNextDescriptorId; - g_uNextDescriptorId++; - - m_szId.setNum(m_uId); - - if(!g_pDescriptorDict) - { - g_pDescriptorDict = new KviPointerHashTable; - g_pDescriptorDict->setAutoDelete(false); - } - g_pDescriptorDict->replace((long)m_uId,this); - - szNick = __tr_ctx("unknown","dcc"); - szUser = szNick; - szHost = szNick; - - szLocalNick = szNick; - szLocalUser = szNick; - szLocalHost = szNick; - - szIp = szNick; - szPort = szNick; - - - bSendRequest = true; - bDoTimeout = true; - bIsTdcc = false; - bOverrideMinimize = false; - bShowMinimized = false; - bAutoAccept = false; -#ifdef COMPILE_SSL_SUPPORT - bIsSSL = false; -#endif - bRecvFile = false; - bResume = false; - bNoAcks = false; - bIsIncomingAvatar = false; - - iSampleRate = 0; - - m_bCreationEventTriggered = false; -} - -KviDccDescriptor::~KviDccDescriptor() -{ - if(m_bCreationEventTriggered) - { - KviWindow * pEventWindow = m_pConsole; - if(!pEventWindow)pEventWindow = g_pApp->activeConsole(); // any console - else { - if(!(g_pApp->windowExists(pEventWindow)))pEventWindow = g_pApp->activeConsole(); - } - - if(pEventWindow) - { - // recheck it again... - if(g_pApp->windowExists(pEventWindow)) - { - KVS_TRIGGER_EVENT_1(KviEvent_OnDCCSessionDestroyed,pEventWindow,m_szId); - } - } - } - - if(g_pDescriptorDict) - { - g_pDescriptorDict->remove((long)m_uId); - if(g_pDescriptorDict->count() < 1) - { - delete g_pDescriptorDict; - g_pDescriptorDict = 0; - } - } - -} - -void KviDccDescriptor::triggerCreationEvent() -{ - if(m_bCreationEventTriggered) - { - qDebug("Ops.. trying to trigger OnDccSessionCreated twice"); - return; - } - m_bCreationEventTriggered = true; - KviWindow * pEventWindow = m_pConsole; - if(!pEventWindow)pEventWindow = g_pApp->activeConsole(); // any console - if(pEventWindow) - { - KVS_TRIGGER_EVENT_1(KviEvent_OnDCCSessionCreated,pEventWindow,m_szId); - } -} - -KviDccDescriptor * KviDccDescriptor::find(unsigned int uId) -{ - if(!g_pDescriptorDict)return 0; - return g_pDescriptorDict->find((long)uId); -} - -void KviDccDescriptor::copyFrom(const KviDccDescriptor &src) -{ - m_uId = g_uNextDescriptorId; - g_uNextDescriptorId++; - m_szId.setNum(m_uId); - - if(!g_pDescriptorDict) - { - g_pDescriptorDict = new KviPointerHashTable; - g_pDescriptorDict->setAutoDelete(false); - } - g_pDescriptorDict->replace((long)m_uId,this); - m_bCreationEventTriggered=false; - - m_pDccWindow = src.m_pDccWindow; - m_pDccTransfer = src.m_pDccTransfer; - szType = src.szType; - szNick = src.szNick; - szUser = src.szUser; - szHost = src.szHost; - szLocalNick = src.szLocalNick; - szLocalUser = src.szLocalUser; - szLocalHost = src.szLocalHost; - szIp = src.szIp; - szPort = src.szPort; - m_pConsole = src.console(); - m_szZeroPortRequestTag= src.zeroPortRequestTag(); - bActive = src.bActive; - szListenIp = src.szListenIp; - szListenPort = src.szListenPort; - szFakeIp = src.szFakeIp; - szFakePort = src.szFakePort; - bSendRequest = src.bSendRequest; - bDoTimeout = src.bDoTimeout; - szFileName = src.szFileName; - szFileSize = src.szFileSize; - bResume = src.bResume; - bRecvFile = src.bRecvFile; - bNoAcks = src.bNoAcks; - bIsTdcc = src.bIsTdcc; - bOverrideMinimize = src.bOverrideMinimize; - bShowMinimized = src.bShowMinimized; - bAutoAccept = src.bAutoAccept; - bIsIncomingAvatar = src.bIsIncomingAvatar; - szLocalFileName = src.szLocalFileName; - szLocalFileSize = src.szLocalFileSize; -#ifdef COMPILE_SSL_SUPPORT - bIsSSL = src.bIsSSL; -#endif - // dcc voice only - szCodec = src.szCodec; - iSampleRate = src.iSampleRate; -} - -bool KviDccDescriptor::isFileUpload() -{ - if(szType.toUpper()=="SEND")return true; - if(szType.toUpper()=="TSEND")return true; -#ifdef COMPILE_SSL_SUPPORT - if(szType.toUpper()=="SSEND")return true; -#endif - return false; -} - -bool KviDccDescriptor::isFileDownload() -{ - if(szType.toUpper()=="RECV")return true; - if(szType.toUpper()=="TRECV")return true; -#ifdef COMPILE_SSL_SUPPORT - if(szType.toUpper()=="SRECV")return true; -#endif - return false; -} - -bool KviDccDescriptor::isDccChat() -{ - if(szType.toUpper()=="CHAT")return true; -#ifdef COMPILE_SSL_SUPPORT - if(szType.toUpper()=="SCHAT")return true; -#endif - return false; -} diff --git a/src/modules/dcc/descriptor.h b/src/modules/dcc/descriptor.h deleted file mode 100644 index 4cea82e51..000000000 --- a/src/modules/dcc/descriptor.h +++ /dev/null @@ -1,158 +0,0 @@ -#ifndef _DESCRIPTOR_H_ -#define _DESCRIPTOR_H_ -//============================================================================= -// -// File : descriptor.h -// Creation date : Tue Jul 23 01:11:52 2002 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2002-2010 Szymon Stefanek (oragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "KviCString.h" -#include "KviConsoleWindow.h" -#include "KviPointerHashTable.h" - -class KviDccWindow; -class KviDccFileTransfer; -class KviDccDescriptor -{ -public: - KviDccDescriptor(KviConsoleWindow * pConsole); - KviDccDescriptor(const KviDccDescriptor & src); - - ~KviDccDescriptor(); -protected: - KviConsoleWindow * m_pConsole; - - // mIrc zero port reverse send/chat extension - KviCString m_szZeroPortRequestTag; - - unsigned int m_uId; // this dcc session ID - QString m_szId; - - KviDccWindow * m_pDccWindow; // 0 if it has no window - KviDccFileTransfer * m_pDccTransfer; // 0 if it is not a transfer - - bool m_bCreationEventTriggered; -public: - // A console that this DCC is bound to (might be replaced while we wait for user acknowledge in dialogs) - KviConsoleWindow * console() const { return m_pConsole; }; - void setConsole(KviConsoleWindow * c){ m_pConsole = c; }; - - KviDccWindow * window() const { return m_pDccWindow; }; - void setWindow(KviDccWindow * w){ m_pDccWindow = w; }; - - KviDccFileTransfer * transfer() const { return m_pDccTransfer; }; - void setTransfer(KviDccFileTransfer * t){ m_pDccTransfer = t; }; - - // mIrc zero port reverse send/chat extension - bool isZeroPortRequest() const { return m_szZeroPortRequestTag.hasData(); }; - const char * zeroPortRequestTag() const { return m_szZeroPortRequestTag.ptr(); }; - void setZeroPortRequestTag(const KviCString &szTag){ m_szZeroPortRequestTag = szTag; }; - - unsigned int id() const { return m_uId; }; - const QString & idString() const { return m_szId; }; - static KviDccDescriptor * find(unsigned int uId); - static KviPointerHashTable * descriptorDict(); - - void triggerCreationEvent(); // this MUST be called by the creator of the descriptor! -private: - void copyFrom(const KviDccDescriptor &src); -public: - // Generic parameters - QString szType; // DCC protocol : CHAT, SCHAT, SEND, TSSEND.... - - bool bActive; // active or passive connection ? - - QString szNick; // remote user nickname - QString szUser; // remote user name (unknown for passive dcc) - QString szHost; // remote user host (unknown for passive dcc) - - QString szLocalNick; // local user nickname (always from irc) - QString szLocalUser; // local user username (always from irc) - QString szLocalHost; // local user hostname (always from irc) - - QString szIp; // remote user ip (active dcc only) - QString szPort; // remote user port (active dcc only) - - QString szListenIp; // passive only : ip to listen on - QString szListenPort; // passive only : port to listen on - - bool bSendRequest; // passive only : true if we have to send the CTCP request - - QString szFakeIp; // passive only : fake ip to send in the CTCP - QString szFakePort; // passive only : fake port to send in the CTCP - - bool bDoTimeout; // the marshall has to setup a timeout ? - - bool bIsTdcc; // is this a TDCC ? - - bool bOverrideMinimize; // Override the default minimize option ? - bool bShowMinimized; // Show minimized ? (valid if bOverrideMinimize is true) - - bool bAutoAccept; // Auto accepted dcc send/chat ? -#ifdef COMPILE_SSL_SUPPORT - bool bIsSSL; // do we have to use SSL ? -#endif - // Specific parameters - - // DCC SEND/RECV - - QString szFileName; // RECVFILE: incoming file name, SENDFILE: filename sent to the remote end - QString szFileSize; // RECVFILE: incoming file size, SENDFILE: remote resume size - - QString szLocalFileName; // RECVFILE: save file name selected, SENDFILE: file to send - QString szLocalFileSize; // RECVFILE: local file size (to resume), SENDFILE: file to send size - - bool bRecvFile; // do we have to RECEIVE the file or SEND it ? - bool bResume; // do we want to resume ? - bool bNoAcks; // blind dcc send ? (do not receive nor send acknowledges) - - bool bIsIncomingAvatar; // It is an Incoming Avatar DCC SEND ? - - // DCC VOICE - KviCString szCodec; // codec name - int iSampleRate; // Sample rate -public: - QString protocol() const { return szType; }; - bool isActive() const { return bActive; }; - QString remoteNick() const { return szNick; }; - QString remoteUser() const { return szUser; }; - QString remoteHost() const { return szHost; }; - QString remoteIp() const { return szIp; }; - QString remotePort() const { return szPort; }; - QString remoteFileName() const { return szFileName; }; - QString remoteFileSize() const { return szFileSize; }; - QString localNick() const { return szLocalNick; }; - QString localUser() const { return szLocalUser; }; - QString localHost() const { return szLocalHost; }; - QString localIp() const { return szIp; }; - QString localPort() const { return szPort; }; - QString localFileName() const { return szLocalFileName; }; - QString localFileSize() const { return szLocalFileSize; }; - bool isFileUpload(); - bool isFileDownload(); - bool isDccChat(); - bool isFileTransfer(){ return (isFileUpload() || isFileDownload()); }; -#ifdef COMPILE_SSL_SUPPORT - bool isSSL() const { return bIsSSL; }; -#endif -}; - -#endif //_DESCRIPTOR_H_ diff --git a/src/modules/dcc/dialogs.cpp b/src/modules/dcc/dialogs.cpp deleted file mode 100644 index 75ceb8cc0..000000000 --- a/src/modules/dcc/dialogs.cpp +++ /dev/null @@ -1,226 +0,0 @@ -//============================================================================= -// -// File : dialogs.cpp -// Creation date : Tue Sep 19 09 2000 15:23:12 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "dialogs.h" - -#include "KviLocale.h" -#include "KviIconManager.h" -#include "KviApplication.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -KviDccBox::KviDccBox(KviDccBroker * br,KviDccDescriptor * dcc) -{ - m_pDescriptor = dcc; - m_pBroker = br; -} - -KviDccBox::~KviDccBox() -{ - if(m_pDescriptor)delete m_pDescriptor; - m_pDescriptor = 0; - m_pBroker->unregisterDccBox(this); -} - -void KviDccBox::forgetDescriptor() -{ - m_pDescriptor = 0; -} - -KviDccAcceptBox::KviDccAcceptBox(KviDccBroker * br,KviDccDescriptor * dcc,const QString &text,const QString &capt) -: QWidget(0), KviDccBox(br,dcc) -{ - setObjectName("dcc_accept_box"); - //QVBoxLayout * vb = new QVBoxLayout(this,4,4); - QVBoxLayout * vb = new QVBoxLayout(this); - vb->setMargin(4); - vb->setSpacing(4); - QLabel * l = new QLabel(text,this); - l->setWordWrap(true); - vb->addWidget(l); - - //QHBoxLayout *hb = new QHBoxLayout(4); - QHBoxLayout *hb = new QHBoxLayout(); - hb->setSpacing(4); - vb->addLayout(hb,Qt::AlignCenter); - QPushButton * btn = new QPushButton(__tr2qs_ctx("&Accept","dcc"),this); - btn->setDefault(true); - //btn->setFocus(); - hb->addWidget(btn); - connect(btn,SIGNAL(clicked()),this,SLOT(acceptClicked())); - btn = new QPushButton(__tr2qs_ctx("&Reject","dcc"),this); - connect(btn,SIGNAL(clicked()),this,SLOT(rejectClicked())); - hb->addWidget(btn); - - setWindowIcon(QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DCCMSG)))); - setWindowTitle(capt); - - l->activateWindow(); - l->setFocus(); -} - -KviDccAcceptBox::~KviDccAcceptBox() -{ -} - -void KviDccAcceptBox::acceptClicked() -{ - hide(); - emit accepted(this,m_pDescriptor); - this->deleteLater(); - //g_pApp->collectGarbage(this); -} - -void KviDccAcceptBox::rejectClicked() -{ - hide(); - emit rejected(this,m_pDescriptor); - this->deleteLater(); - //g_pApp->collectGarbage(this); -} - -void KviDccAcceptBox::closeEvent(QCloseEvent *e) -{ - hide(); - e->ignore(); - emit rejected(this,m_pDescriptor); - this->deleteLater(); - //g_pApp->collectGarbage(this); -} - -void KviDccAcceptBox::showEvent(QShowEvent *e) -{ - QRect rect = g_pApp->desktop()->screenGeometry(g_pApp->desktop()->primaryScreen()); - move((rect.width() - width())/2,(rect.height() - height())/2); - QWidget::showEvent(e); -} - - -KviDccRenameBox::KviDccRenameBox(KviDccBroker * br,KviDccDescriptor * dcc,const QString &text,bool bDisableResume) -: QWidget(0), KviDccBox(br,dcc) -{ - setObjectName("dcc_rename_box"); - //QVBoxLayout * vb = new QVBoxLayout(this,4,4); - QVBoxLayout * vb = new QVBoxLayout(this); - vb->setMargin(4); - vb->setSpacing(4); - QLabel * l = new QLabel(text,this); - l->setWordWrap(true); - vb->addWidget(l); - - //QHBoxLayout *hb = new QHBoxLayout(4); - QHBoxLayout *hb = new QHBoxLayout(); - hb->setSpacing(4); - vb->addLayout(hb,Qt::AlignCenter); - - QPushButton * btn = new QPushButton(__tr2qs_ctx("&Rename","dcc"),this); - hb->addWidget(btn); - connect(btn,SIGNAL(clicked()),this,SLOT(renameClicked())); - - btn = new QPushButton(__tr2qs_ctx("Over&write","dcc"),this); - hb->addWidget(btn); - connect(btn,SIGNAL(clicked()),this,SLOT(overwriteClicked())); - - btn = new QPushButton(__tr2qs_ctx("Re&sume","dcc"),this); - hb->addWidget(btn); - connect(btn,SIGNAL(clicked()),this,SLOT(resumeClicked())); - if(bDisableResume)btn->setEnabled(false); - - btn = new QPushButton(__tr2qs_ctx("Cancel","dcc"),this); - hb->addWidget(btn); - connect(btn,SIGNAL(clicked()),this,SLOT(cancelClicked())); - btn->setDefault(true); - //btn->setFocus(); - - setWindowIcon(QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DCCMSG)))); - setWindowTitle(__tr2qs_ctx("File Already Exists - KVIrc","dcc")); -} - -KviDccRenameBox::~KviDccRenameBox() -{ -} - -void KviDccRenameBox::closeEvent(QCloseEvent *e) -{ - hide(); - e->ignore(); - if(m_pDescriptor) - { - emit cancelSelected(this,m_pDescriptor); - //g_pApp->collectGarbage(this); - this->deleteLater(); - } -} - -void KviDccRenameBox::showEvent(QShowEvent *e) -{ - move((g_pApp->desktop()->width() - width()) >> 1, - (g_pApp->desktop()->height() - height()) >> 1); - QWidget::showEvent(e); -} - -void KviDccRenameBox::renameClicked() -{ - hide(); - emit renameSelected(this,m_pDescriptor); - //g_pApp->collectGarbage(this); - this->deleteLater(); -} - -void KviDccRenameBox::overwriteClicked() -{ - hide(); - emit overwriteSelected(this,m_pDescriptor); - //g_pApp->collectGarbage(this); - this->deleteLater(); -} - -void KviDccRenameBox::resumeClicked() -{ - hide(); - m_pDescriptor->bResume = true; - emit overwriteSelected(this,m_pDescriptor); - this->deleteLater(); - //g_pApp->collectGarbage(this); -} - -void KviDccRenameBox::cancelClicked() -{ - hide(); - emit cancelSelected(this,m_pDescriptor); - this->deleteLater(); - //g_pApp->collectGarbage(this); -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_dialogs.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/dcc/dialogs.h b/src/modules/dcc/dialogs.h deleted file mode 100644 index 6e1081893..000000000 --- a/src/modules/dcc/dialogs.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef _DIALOGS_H_ -#define _DIALOGS_H_ -//============================================================================= -// -// File : dialogs.h -// Creation date : Tue Sep 19 09 2000 15:17:22 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "broker.h" - -#include "KviFileDialog.h" - -#include - -class KviDccBox -{ -protected: - KviDccDescriptor * m_pDescriptor; - KviDccBroker * m_pBroker; -public: - KviDccBox(KviDccBroker * br,KviDccDescriptor * dcc); - virtual ~KviDccBox(); -public: - virtual void forgetDescriptor(); -}; - - -class KviDccAcceptBox : public QWidget, public KviDccBox -{ - Q_OBJECT -public: - KviDccAcceptBox(KviDccBroker * br,KviDccDescriptor * dcc,const QString &text,const QString &capt); - ~KviDccAcceptBox(); -protected: - virtual void closeEvent(QCloseEvent *e); - virtual void showEvent(QShowEvent *e); -private slots: - void acceptClicked(); - void rejectClicked(); -signals: - void accepted(KviDccBox *,KviDccDescriptor *); - void rejected(KviDccBox *,KviDccDescriptor *); -}; - -class KviDccRenameBox : public QWidget, public KviDccBox -{ - Q_OBJECT -public: - KviDccRenameBox(KviDccBroker * br,KviDccDescriptor * dcc,const QString &text,bool bDisableResume); - ~KviDccRenameBox(); -protected: - virtual void closeEvent(QCloseEvent *e); - virtual void showEvent(QShowEvent *e); -private slots: - void renameClicked(); - void overwriteClicked(); - void resumeClicked(); - void cancelClicked(); -signals: - void overwriteSelected(KviDccBox *,KviDccDescriptor *); - void renameSelected(KviDccBox *,KviDccDescriptor *); - void cancelSelected(KviDccBox *,KviDccDescriptor *); -}; - -#endif diff --git a/src/modules/dcc/gsmcodec.cpp b/src/modules/dcc/gsmcodec.cpp deleted file mode 100644 index 21635ebd9..000000000 --- a/src/modules/dcc/gsmcodec.cpp +++ /dev/null @@ -1,148 +0,0 @@ -//============================================================================= -// -// File : gsmcodec.cpp -// Creation date : Wed Aug 22 19:12:55 2001 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#define _GSMCODEC_CPP_ - -#include "gsmcodec.h" - -#ifdef COMPILE_USE_GSM - #include - - #define GSM_PACKED_FRAME_SIZE_IN_BYTES 33 - #define GSM_UNPACKED_FRAME_SIZE_IN_BYTES 320 - #define GSM_UNPACKED_FRAME_SIZE_IN_SHORTS 160 - - void * (*gsm_session_create)() = 0; - void (*gsm_session_destroy)(void *) = 0; - void (*gsm_session_encode)(void *,short *,unsigned char *) = 0; - int (*gsm_session_decode)(void *,unsigned char *,short *) = 0; - - void * g_pGSMCodecLibraryHandle = 0; - - bool kvi_gsm_codec_init() - { - if(g_pGSMCodecLibraryHandle)return true; // Already initialized - - g_pGSMCodecLibraryHandle = dlopen("libgsm.so",RTLD_NOW | RTLD_GLOBAL); - if(!g_pGSMCodecLibraryHandle)return false; // no way to open it - - gsm_session_create = (void * (*)()) dlsym(g_pGSMCodecLibraryHandle,"gsm_create"); - gsm_session_destroy = (void (*)(void *)) dlsym(g_pGSMCodecLibraryHandle,"gsm_destroy"); - gsm_session_encode = (void (*)(void *,short *,unsigned char *)) dlsym(g_pGSMCodecLibraryHandle,"gsm_encode"); - gsm_session_decode = (int (*)(void *,unsigned char *,short *)) dlsym(g_pGSMCodecLibraryHandle,"gsm_decode"); - - if(! (gsm_session_create && gsm_session_destroy && gsm_session_encode && gsm_session_decode)) - { - dlclose(g_pGSMCodecLibraryHandle); - g_pGSMCodecLibraryHandle = 0; - return false; - } - return true; - } - - void kvi_gsm_codec_done() - { - if(g_pGSMCodecLibraryHandle) - { - dlclose(g_pGSMCodecLibraryHandle); - g_pGSMCodecLibraryHandle = 0; - } - } - - - KviDccVoiceGsmCodec::KviDccVoiceGsmCodec() - : KviDccVoiceCodec() - { - m_pEncodeState = gsm_session_create(); - m_pDecodeState = gsm_session_create(); - m_szName = "gsm (compression 33:320)"; - } - - KviDccVoiceGsmCodec::~KviDccVoiceGsmCodec() - { - gsm_session_destroy(m_pEncodeState); - gsm_session_destroy(m_pDecodeState); - } - - void KviDccVoiceGsmCodec::encode(KviDataBuffer * signal,KviDataBuffer * stream) - { - if(signal->size() < GSM_UNPACKED_FRAME_SIZE_IN_BYTES)return; // nothing to encode - - unsigned char * ptr = signal->data(); - - int uFrames = signal->size() / GSM_UNPACKED_FRAME_SIZE_IN_BYTES; - int uTotalDataCompressed = uFrames * GSM_UNPACKED_FRAME_SIZE_IN_BYTES; - int uFrameOffset = stream->size(); - unsigned char * endPtr = ptr + uTotalDataCompressed; - - stream->addSize(GSM_PACKED_FRAME_SIZE_IN_BYTES * uFrames); - - while(ptr != endPtr) - { - gsm_session_encode(m_pEncodeState,(short *)ptr,stream->data() + uFrameOffset); - ptr += GSM_UNPACKED_FRAME_SIZE_IN_BYTES; - uFrameOffset += GSM_PACKED_FRAME_SIZE_IN_BYTES; - } - signal->remove(uTotalDataCompressed); - } - - void KviDccVoiceGsmCodec::decode(KviDataBuffer * stream,KviDataBuffer * signal) - { - if(stream->size() < GSM_PACKED_FRAME_SIZE_IN_BYTES)return; // nothing to decode - - unsigned char * ptr = stream->data(); - - // Gsm codec - int uFrames = stream->size() / GSM_PACKED_FRAME_SIZE_IN_BYTES; - int uTotalDataDecompressed = uFrames * GSM_PACKED_FRAME_SIZE_IN_BYTES; - int uSignalOffset = signal->size(); - unsigned char * endPtr = ptr + (uTotalDataDecompressed); - - signal->addSize(GSM_UNPACKED_FRAME_SIZE_IN_BYTES * uFrames); - - while(ptr != endPtr) - { - // We don't check the return value here - // Well..it is either an unrecoverable internal error - // or a broken frame... - // but if we receive broken frames over DCC...well....better - // check the hardware...or the remote codec as well... - gsm_session_decode(m_pDecodeState,ptr,(short *)(signal->data() + uSignalOffset)); - ptr += GSM_PACKED_FRAME_SIZE_IN_BYTES; - uSignalOffset += GSM_UNPACKED_FRAME_SIZE_IN_BYTES; - } - stream->remove(uTotalDataDecompressed); - } - - int KviDccVoiceGsmCodec::encodedFrameSize() - { - return GSM_PACKED_FRAME_SIZE_IN_BYTES; - } - - int KviDccVoiceGsmCodec::decodedFrameSize() - { - return GSM_UNPACKED_FRAME_SIZE_IN_BYTES; - } - -#endif // COMPILE_USE_GSM diff --git a/src/modules/dcc/gsmcodec.h b/src/modules/dcc/gsmcodec.h deleted file mode 100644 index 27971f87c..000000000 --- a/src/modules/dcc/gsmcodec.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef _GSMCODEC_H_ -#define _GSMCODEC_H_ -//============================================================================= -// -// File : gsmcodec.h -// Creation date : Wed Aug 22 19:12:54 2001 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "kvi_settings.h" - - -#ifdef COMPILE_USE_GSM - - #include "codec.h" - - #ifndef _GSMCODEC_CPP_ - extern bool kvi_gsm_codec_init(); - extern void kvi_gsm_codec_done(); - #endif //_GSMCODEC_CPP_ - - class KviDccVoiceGsmCodec : public KviDccVoiceCodec - { - public: - KviDccVoiceGsmCodec(); - virtual ~KviDccVoiceGsmCodec(); - private: - void * m_pEncodeState; - void * m_pDecodeState; - public: - virtual void encode(KviDataBuffer * signal,KviDataBuffer * stream); - virtual void decode(KviDataBuffer * stream,KviDataBuffer * signal); - virtual int encodedFrameSize(); - virtual int decodedFrameSize(); - }; - -#endif //COMPILE_USE_GSM - -#endif //_GSMCODEC_H_ diff --git a/src/modules/dcc/libkvidcc.cpp b/src/modules/dcc/libkvidcc.cpp index 596802962..54b60de54 100644 --- a/src/modules/dcc/libkvidcc.cpp +++ b/src/modules/dcc/libkvidcc.cpp @@ -22,13 +22,13 @@ // //============================================================================= -#include "gsmcodec.h" -#include "broker.h" -#include "voice.h" -#include "video.h" -#include "utils.h" -#include "send.h" -#include "window.h" +#include "DccVoiceGsmCodec.h" +#include "DccBroker.h" +#include "DccVoiceWindow.h" +#include "DccVideoWindow.h" +#include "DccUtils.h" +#include "DccFileTransfer.h" +#include "DccWindow.h" #include "kvi_debug.h" #include "kvi_settings.h" @@ -53,17 +53,17 @@ #ifdef COMPILE_ON_WINDOWS // Ugly Windoze compiler... - #include "dialogs.h" + #include "DccDialog.h" #endif //#warning "KviOption_boolIgnoreDccChat and other types too" //extern KVIRC_API KviSharedFilesManager * g_pSharedFilesManager; -KviDccBroker * g_pDccBroker = 0; +DccBroker * g_pDccBroker = 0; -static void dcc_module_set_dcc_type(KviDccDescriptor * d,const char * szBaseType) +static void dcc_module_set_dcc_type(DccDescriptor * d,const char * szBaseType) { d->szType = szBaseType; #ifdef COMPILE_SSL_SUPPORT @@ -72,7 +72,7 @@ static void dcc_module_set_dcc_type(KviDccDescriptor * d,const char * szBaseType if(d->bIsTdcc)d->szType.prepend('T'); } -static bool dcc_kvs_parse_default_parameters(KviDccDescriptor * d,KviKvsModuleCommandCall *c) +static bool dcc_kvs_parse_default_parameters(DccDescriptor * d,KviKvsModuleCommandCall *c) { d->bIsTdcc = c->switches()->find('t',"tdcc"); @@ -401,7 +401,7 @@ static bool dcc_kvs_cmd_chat(KviKvsModuleCommandCall * c) KVSM_PARAMETER("target",KVS_PT_NONEMPTYSTRING,0,szTarget) KVSM_PARAMETERS_END(c) - KviDccDescriptor * d = new KviDccDescriptor(c->window()->console()); + DccDescriptor * d = new DccDescriptor(c->window()->console()); d->szNick = szTarget; // we always specify the nickname d->szUser = __tr2qs_ctx("unknown","dcc"); // username is always unknown @@ -610,7 +610,7 @@ static bool dcc_kvs_cmd_send(KviKvsModuleCommandCall * c) KVSM_PARAMETER("file name",KVS_PT_NONEMPTYSTRING,KVS_PF_OPTIONAL,szFileName) KVSM_PARAMETERS_END(c) - KviDccDescriptor * d = new KviDccDescriptor(c->window()->console()); + DccDescriptor * d = new DccDescriptor(c->window()->console()); d->szNick = szTarget; // we always specify the nickname @@ -797,7 +797,7 @@ static bool dcc_kvs_cmd_recv(KviKvsModuleCommandCall * c) KVSM_PARAMETER("size",KVS_PT_UINT,0,uSize) KVSM_PARAMETERS_END(c) - KviDccDescriptor * d = new KviDccDescriptor(c->window()->console()); + DccDescriptor * d = new DccDescriptor(c->window()->console()); d->szNick = szTarget; d->szUser = __tr2qs_ctx("unknown","dcc"); d->szHost = d->szUser; @@ -879,7 +879,7 @@ static bool dcc_kvs_cmd_rsend(KviKvsModuleCommandCall * c) KVSM_REQUIRE_CONNECTION(c) - KviDccDescriptor * d = new KviDccDescriptor(c->window()->console()); + DccDescriptor * d = new DccDescriptor(c->window()->console()); d->szNick = szTarget; d->szLocalFileName = szFileName; d->bIsTdcc = c->switches()->find('t',"tdcc"); @@ -1114,7 +1114,7 @@ static bool dcc_kvs_cmd_voice(KviKvsModuleCommandCall * c) return true; #endif - KviDccDescriptor * d = new KviDccDescriptor(c->window()->console()); + DccDescriptor * d = new DccDescriptor(c->window()->console()); d->szNick = szTarget; // we always specify the nickname d->szUser = __tr2qs_ctx("unknown","dcc"); // username is always unknown @@ -1192,7 +1192,7 @@ static bool dcc_kvs_cmd_video(KviKvsModuleCommandCall * c) return true; #else - KviDccDescriptor * d = new KviDccDescriptor(c->window()->console()); + DccDescriptor * d = new DccDescriptor(c->window()->console()); d->szNick = szTarget; // we always specify the nickname d->szUser = __tr2qs_ctx("unknown","dcc"); // username is always unknown @@ -1258,7 +1258,7 @@ static bool dcc_module_cmd_canvas(KviModule *m,KviCommand *c) if(target.isEmpty())return c->error(KviError_notEnoughParameters,"%s",__tr_ctx("Missing target nickname","dcc")); - KviDccDescriptor * d = new KviDccDescriptor(c->window()->console()); + DccDescriptor * d = new DccDescriptor(c->window()->console()); d->szNick = target.ptr(); // we always specify the nickname d->szUser = __tr2qs_ctx("unknown","dcc"); // username is always unknown @@ -1628,20 +1628,20 @@ static bool dcc_module_cmd_canvas(KviModule *m,KviCommand *c) "XDCC" has exactly the same meaning as "DCC" (at least in KVIrc).[br] */ -static KviDccDescriptor * dcc_kvs_find_dcc_descriptor(const kvs_uint_t &uId,KviKvsModuleRunTimeCall * c,bool bWarn = true) +static DccDescriptor * dcc_kvs_find_dcc_descriptor(const kvs_uint_t &uId,KviKvsModuleRunTimeCall * c,bool bWarn = true) { - KviDccDescriptor * dcc = 0; + DccDescriptor * dcc = 0; if(uId == 0) { - if(c->window()->inherits("KviDccWindow")) + if(c->window()->inherits("DccWindow")) { - dcc = ((KviDccWindow *)(c->window()))->descriptor(); + dcc = ((DccWindow *)(c->window()))->descriptor(); } if((!dcc) && bWarn) c->warning(__tr2qs_ctx("The current window has no associated DCC session","dcc")); return dcc; } - dcc = KviDccDescriptor::find(uId); + dcc = DccDescriptor::find(uId); if((!dcc) && bWarn) c->warning(__tr2qs_ctx("The specified parameter is not a valid DCC identifier","dcc")); return dcc; @@ -1679,7 +1679,7 @@ static bool dcc_kvs_cmd_abort(KviKvsModuleCommandCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c,!c->switches()->find('q',"quiet")); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c,!c->switches()->find('q',"quiet")); if(dcc) { @@ -1719,7 +1719,7 @@ static bool dcc_kvs_cmd_setBandwidthLimit(KviKvsModuleCommandCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c,!c->switches()->find('q',"quiet")); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c,!c->switches()->find('q',"quiet")); if(dcc) { if (dcc->transfer())dcc->transfer()->setBandwidthLimit(uVal); @@ -1757,7 +1757,7 @@ static bool dcc_kvs_fnc_protocol(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setString(dcc->protocol()); return true; @@ -1794,7 +1794,7 @@ static bool dcc_kvs_fnc_connectionType(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setString(dcc->isActive() ? "ACTIVE" : "PASSIVE"); return true; @@ -1830,7 +1830,7 @@ static bool dcc_kvs_fnc_isFileTransfer(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c,false); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c,false); if(dcc)c->returnValue()->setBoolean(dcc->isFileTransfer()); return true; @@ -1866,7 +1866,7 @@ static bool dcc_kvs_fnc_isFileUpload(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setBoolean(dcc->isFileUpload()); return true; @@ -1902,7 +1902,7 @@ static bool dcc_kvs_fnc_isFileDownload(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setBoolean(dcc->isFileDownload()); return true; @@ -1937,7 +1937,7 @@ static bool dcc_kvs_fnc_localNick(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setString(dcc->localNick()); return true; @@ -1972,7 +1972,7 @@ static bool dcc_kvs_fnc_localUser(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setString(dcc->localUser()); return true; @@ -2006,7 +2006,7 @@ static bool dcc_kvs_fnc_localHost(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setString(dcc->localHost()); return true; @@ -2041,7 +2041,7 @@ static bool dcc_kvs_fnc_localIp(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setString(dcc->localIp()); return true; @@ -2075,7 +2075,7 @@ static bool dcc_kvs_fnc_localPort(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setString(dcc->localPort()); return true; @@ -2107,7 +2107,7 @@ static bool dcc_kvs_fnc_localFileName(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setString(dcc->localFileName()); return true; @@ -2144,7 +2144,7 @@ static bool dcc_kvs_fnc_localFileSize(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setString(dcc->localFileSize().isEmpty() ? QString("0") : dcc->localFileSize()); return true; @@ -2179,7 +2179,7 @@ static bool dcc_kvs_fnc_remoteNick(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setString(dcc->remoteNick()); return true; @@ -2214,7 +2214,7 @@ static bool dcc_kvs_fnc_remoteUser(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setString(dcc->remoteUser()); return true; @@ -2248,7 +2248,7 @@ static bool dcc_kvs_fnc_remoteHost(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setString(dcc->remoteHost()); return true; @@ -2282,7 +2282,7 @@ static bool dcc_kvs_fnc_remoteIp(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setString(dcc->remoteIp()); return true; @@ -2317,7 +2317,7 @@ static bool dcc_kvs_fnc_remotePort(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setString(dcc->remotePort()); return true; @@ -2349,7 +2349,7 @@ static bool dcc_kvs_fnc_remoteFileName(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setString(dcc->remoteFileName()); return true; @@ -2386,7 +2386,7 @@ static bool dcc_kvs_fnc_remoteFileSize(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setString(dcc->remoteFileSize().isEmpty() ? QString("0") : dcc->remoteFileSize()); return true; @@ -2424,7 +2424,7 @@ static bool dcc_kvs_fnc_ircContext(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc)c->returnValue()->setInteger(dcc->console()->context()->id()); return true; @@ -2464,7 +2464,7 @@ static bool dcc_kvs_fnc_transferStatus(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc) { @@ -2509,7 +2509,7 @@ static bool dcc_kvs_fnc_transferredBytes(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc) { @@ -2555,7 +2555,7 @@ static bool dcc_kvs_fnc_averageSpeed(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("dcc_id",KVS_PT_UINT,KVS_PF_OPTIONAL,uDccId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc) { @@ -2596,11 +2596,11 @@ static bool dcc_kvs_fnc_session(KviKvsModuleFunctionCall * c) KVSM_PARAMETER("window_id",KVS_PT_STRING,KVS_PF_OPTIONAL,szWinId) KVSM_PARAMETERS_END(c) - KviDccDescriptor * dcc = 0; + DccDescriptor * dcc = 0; if(szWinId.isEmpty()) { - if(c->window()->inherits("KviDccWindow")) - dcc = ((KviDccWindow *)(c->window()))->descriptor(); + if(c->window()->inherits("DccWindow")) + dcc = ((DccWindow *)(c->window()))->descriptor(); if(!dcc) { c->warning(__tr2qs_ctx("The current window has no associated DCC session","dcc")); @@ -2619,8 +2619,8 @@ static bool dcc_kvs_fnc_session(KviKvsModuleFunctionCall * c) return true; } - if(pWnd->inherits("KviDccWindow")) - dcc = ((KviDccWindow *)pWnd)->descriptor(); + if(pWnd->inherits("DccWindow")) + dcc = ((DccWindow *)pWnd)->descriptor(); if(!dcc) { c->warning(__tr2qs_ctx("The current window has no associated DCC session","dcc")); @@ -2662,17 +2662,17 @@ static bool dcc_kvs_fnc_sessionList(KviKvsModuleFunctionCall * c) KviKvsArray * a = new KviKvsArray(); c->returnValue()->setArray(a); - KviPointerHashTable * dict = KviDccDescriptor::descriptorDict(); + KviPointerHashTable * dict = DccDescriptor::descriptorDict(); if(!dict)return true; - KviPointerHashTableIterator it(*dict); + KviPointerHashTableIterator it(*dict); int idx = 0; if(szFlags.isEmpty()) { // all - while(KviDccDescriptor * dcc = it.current()) + while(DccDescriptor * dcc = it.current()) { a->set(idx++,new KviKvsVariant((kvs_int_t)(dcc->id()))); ++it; @@ -2682,7 +2682,7 @@ static bool dcc_kvs_fnc_sessionList(KviKvsModuleFunctionCall * c) bool bWantFileDownloads = szFlags.contains('d',Qt::CaseInsensitive) != -1; bool bWantChats = szFlags.contains('c',Qt::CaseInsensitive) != -1; - while(KviDccDescriptor * dcc = it.current()) + while(DccDescriptor * dcc = it.current()) { if((dcc->isFileUpload() && bWantFileUploads) || (dcc->isFileDownload() && bWantFileDownloads) || @@ -2787,7 +2787,7 @@ static bool dcc_kvs_fnc_getSSLCertInfo(KviKvsModuleFunctionCall * c) return true; } } - KviDccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); + DccDescriptor * dcc = dcc_kvs_find_dcc_descriptor(uDccId,c); if(dcc) { @@ -2798,7 +2798,7 @@ static bool dcc_kvs_fnc_getSSLCertInfo(KviKvsModuleFunctionCall * c) return true; } - KviDccThread * pSlaveThread = 0; + DccThread * pSlaveThread = 0; if(dcc->window()) pSlaveThread = dcc->window()->getSlaveThread(); else if(dcc->transfer()) @@ -2901,7 +2901,7 @@ static bool dcc_kvs_fnc_getSSLCertInfo(KviKvsModuleFunctionCall * c) static bool dcc_module_init(KviModule * m) { - g_pDccBroker = new KviDccBroker(); + g_pDccBroker = new DccBroker(); KVSM_REGISTER_SIMPLE_COMMAND(m,"send",dcc_kvs_cmd_send); KVSM_REGISTER_SIMPLE_COMMAND(m,"chat",dcc_kvs_cmd_chat); diff --git a/src/modules/dcc/marshal.cpp b/src/modules/dcc/marshal.cpp deleted file mode 100644 index b2bbda32f..000000000 --- a/src/modules/dcc/marshal.cpp +++ /dev/null @@ -1,657 +0,0 @@ -//============================================================================= -// -// File : marshal.cpp -// Creation date : Sun Sep 17 2000 15:59:11 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "marshal.h" - -#include "kvi_settings.h" -#include "KviNetUtils.h" -#include "KviOptions.h" -#include "KviLocale.h" -#include "KviMemory.h" -#include "kvi_socket.h" -#include "KviFileUtils.h" - -#include //for exit() - -#include - -KviDccMarshal::KviDccMarshal(KviDccMarshalOutputContext * ctx) -: QObject(0) -{ - setObjectName("dcc_marshal"); - m_pSn = 0; - m_fd = KVI_INVALID_SOCKET; - m_pTimeoutTimer = 0; - m_bIPv6 = false; - m_pOutputContext = ctx; -#ifdef COMPILE_SSL_SUPPORT - m_pSSL = 0; -#endif - m_szIp = ""; - m_szPort = ""; - m_szSecondaryIp = ""; - m_szSecondaryPort = ""; -} - -KviDccMarshal::~KviDccMarshal() -{ - reset(); -} - -kvi_socket_t KviDccMarshal::releaseSocket() -{ - kvi_socket_t aux_fd = m_fd; - m_fd = KVI_INVALID_SOCKET; - return aux_fd; -} - -#ifdef COMPILE_SSL_SUPPORT -KviSSL * KviDccMarshal::releaseSSL() -{ - KviSSL * theSSL = m_pSSL; - m_pSSL = 0; - return theSSL; -} -#endif - -void KviDccMarshal::reset() -{ - if(m_pSn) - { - delete m_pSn; - m_pSn = 0; - } - if(m_fd != KVI_INVALID_SOCKET) - { - kvi_socket_close(m_fd); - m_fd = KVI_INVALID_SOCKET; - } -#ifdef COMPILE_SSL_SUPPORT -// qDebug("MARSHAL RESETTING (SSL=%d)",m_pSSL); - if(m_pSSL) - { -// qDebug("MARSHAL CLEARING THE SSL"); - KviSSLMaster::freeSSL(m_pSSL); - m_pSSL = 0; - } -#endif - if(m_pTimeoutTimer) - { - delete m_pTimeoutTimer; - m_pTimeoutTimer = 0; - } - m_bIPv6 = false; -} - -KviError::Code KviDccMarshal::dccListen(const QString &ip,const QString &port,bool bUseTimeout,bool bUseSSL) -{ - if(m_fd != KVI_INVALID_SOCKET) - return KviError::AnotherConnectionInProgress; - - m_szIp = ip; - m_szPort = port; - - m_bOutgoing = false; - - m_bUseTimeout = bUseTimeout; - - if(m_pTimeoutTimer) - { - delete m_pTimeoutTimer; - m_pTimeoutTimer = 0; - } - -#ifdef COMPILE_SSL_SUPPORT - m_bUseSSL = bUseSSL; -#else - if(bUseSSL) - return KviError::NoSSLSupport; -#endif - QTimer::singleShot(100, this, SLOT(doListen())); - - return KviError::Success; -} - -void KviDccMarshal::doListen() -{ - // Check the address type - if(!KviNetUtils::isValidStringIp(m_szIp)) - { -#ifdef COMPILE_IPV6_SUPPORT - if(!KviNetUtils::isValidStringIPv6(m_szIp)) - { - emit error(KviError::InvalidIpAddress); - return; - } else m_bIPv6 = true; -#else - emit error(KviError::InvalidIpAddress); - return; -#endif - } - - bool bOk; - m_uPort = m_szPort.toUInt(&bOk); - if(!bOk) - { - emit error(KviError::InvalidPortNumber); - return; - } - -#ifndef COMPILE_IPV6_SUPPORT - if(m_bIPv6) - { - emit error(KviError::NoIPv6Support); - return; - } -#endif - - -#ifdef COMPILE_IPV6_SUPPORT - m_fd = kvi_socket_create(m_bIPv6 ? KVI_SOCKET_PF_INET6 : KVI_SOCKET_PF_INET, - KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); -#else - m_fd = kvi_socket_create(KVI_SOCKET_PF_INET,KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); -#endif - - if(m_fd == KVI_INVALID_SOCKET) - { - emit error(KviError::SocketCreationFailed); - return; - } - - if((!KVI_OPTION_BOOL(KviOption_boolUserDefinedPortRange)) || (m_uPort != 0)) - { -#ifdef COMPILE_IPV6_SUPPORT - KviSockaddr sa(m_szIp.toUtf8().data(),m_uPort,m_bIPv6); -#else - KviSockaddr sa(m_szIp.toUtf8().data(),m_uPort,false); -#endif - - if(!sa.socketAddress()) - { - reset(); - emit error(KviError::BindFailed); - return; - } - - if(!kvi_socket_bind(m_fd,sa.socketAddress(),sa.addressLength())) - { - reset(); - emit error(KviError::BindFailed); - return; - } - - } else { - m_uPort = KVI_OPTION_UINT(KviOption_uintDccMinPort); - if(KVI_OPTION_UINT(KviOption_uintDccMaxPort) > 65535)KVI_OPTION_UINT(KviOption_uintDccMaxPort) = 65535; - bool bBindSuccess; - do { -#ifdef COMPILE_IPV6_SUPPORT - KviSockaddr sa(m_szIp.toUtf8().data(),m_uPort,m_bIPv6); -#else - KviSockaddr sa(m_szIp.toUtf8().data(),m_uPort,false); -#endif - if(!sa.socketAddress()) - { - reset(); - emit error(KviError::BindFailed); - return; - } - - bBindSuccess = kvi_socket_bind(m_fd,sa.socketAddress(),sa.addressLength()); - - if(!bBindSuccess) - { - if(m_uPort == 65535) - { - reset(); - emit error(KviError::BindFailed); - return; - } - m_uPort++; - } - - } while((!bBindSuccess) && (m_uPort <= KVI_OPTION_UINT(KviOption_uintDccMaxPort))); - - if(!bBindSuccess) - { - reset(); - emit error(KviError::BindFailed); - return; - } - - } - - if(!kvi_socket_listen(m_fd,1)) - { - reset(); - emit error(KviError::ListenFailed); - return; - } - - - // Reread the port in case we're binding to a random one (0) - -#ifdef COMPILE_IPV6_SUPPORT - KviSockaddr sareal(0,m_bIPv6); -#else - KviSockaddr sareal(0,false); -#endif - - - int size = sareal.addressLength(); - - if(kvi_socket_getsockname(m_fd,sareal.socketAddress(),&size)) - { -// qDebug("GETSOCKNAMEOK"); - m_szPort.setNum(sareal.port()); - m_uPort = sareal.port(); -// qDebug("REALPORT %u",m_uPort); - } else { -// qDebug("GETSOCKNAMEFAILED"); - } - - // and setup the READ notifier... - m_pSn = new QSocketNotifier(m_fd,QSocketNotifier::Read); - QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(snActivated(int))); - m_pSn->setEnabled(true); - - // set the timer - if(KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) < 5) - KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) = 5; - - if(m_pTimeoutTimer) - { - delete m_pTimeoutTimer; - m_pTimeoutTimer = 0; - } - - if(m_bUseTimeout) - { - m_pTimeoutTimer = new QTimer(); - connect(m_pTimeoutTimer,SIGNAL(timeout()),this,SLOT(connectionTimedOut())); - m_pTimeoutTimer->setSingleShot(true); - m_pTimeoutTimer->setInterval((KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) * 1000)); - m_pTimeoutTimer->start(); - } - // and wait for connect - - emit inProgress(); -} - -KviError::Code KviDccMarshal::dccConnect(const char * ip,const char * port,bool bUseTimeout,bool bUseSSL) -{ - if(m_fd != KVI_INVALID_SOCKET) - return KviError::AnotherConnectionInProgress; - - m_bUseTimeout = bUseTimeout; - m_szIp = ip; - m_szPort = port; - m_bOutgoing = true; - -#ifdef COMPILE_SSL_SUPPORT - m_bUseSSL = bUseSSL; -#else - if(bUseSSL) - return KviError::NoSSLSupport; -#endif - - QTimer::singleShot(100, this, SLOT(doConnect())); - return KviError::Success; -} - -void KviDccMarshal::doConnect() -{ - if(m_pTimeoutTimer) - { - delete m_pTimeoutTimer; - m_pTimeoutTimer = 0; - } - // Check the address type - if(!KviNetUtils::isValidStringIp(m_szIp)) - { -#ifdef COMPILE_IPV6_SUPPORT - if(!KviNetUtils::isValidStringIPv6(m_szIp)) - { - emit error(KviError::InvalidIpAddress); - return; - } else m_bIPv6 = true; -#else - emit error(KviError::InvalidIpAddress); - return; -#endif - } - - bool bOk; - m_uPort = m_szPort.toUInt(&bOk); - if(!bOk) - { - emit error(KviError::InvalidPortNumber); - return; - } - - - // create the socket -#ifdef COMPILE_IPV6_SUPPORT - m_fd = kvi_socket_create(m_bIPv6 ? KVI_SOCKET_PF_INET6 : KVI_SOCKET_PF_INET, - KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); -#else - m_fd = kvi_socket_create(KVI_SOCKET_PF_INET, - KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); -#endif - if(m_fd == KVI_INVALID_SOCKET) - { - emit error(KviError::SocketCreationFailed); - return; - } - - // make it non blocking - if(!kvi_socket_setNonBlocking(m_fd)) - { - reset(); - emit error(KviError::AsyncSocketFailed); - return; - } - - - // fill the sockaddr structure - -#ifdef COMPILE_IPV6_SUPPORT - KviSockaddr sa(m_szIp.toUtf8().data(),m_uPort,m_bIPv6); -#else - KviSockaddr sa(m_szIp.toUtf8().data(),m_uPort,false); -#endif - - if(!sa.socketAddress()) - { - reset(); - emit error(KviError::SocketCreationFailed); - return; - } - - if(!kvi_socket_connect(m_fd,sa.socketAddress(),sa.addressLength())) - { - int err = kvi_socket_error(); - - if(!kvi_socket_recoverableConnectError(err)) - { - // Ops... - int sockError=err; - if(sockError==0) - { - // Zero error ?...let's look closer - int iSize=sizeof(int); - if(!kvi_socket_getsockopt(m_fd,SOL_SOCKET,SO_ERROR, - (void *)&sockError,&iSize))sockError=0; - } - // Die - reset(); - // And declare problems :) - if(sockError)emit error(KviError::translateSystemError(sockError)); - else emit error(KviError::UnknownError); //Error 0 ? - return; - } - } - - - // and setup the WRITE notifier... - m_pSn = new QSocketNotifier(m_fd,QSocketNotifier::Write); - QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(snActivated(int))); - m_pSn->setEnabled(true); - - // set the timer - if(KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) < 5) - KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) = 5; - - if(m_pTimeoutTimer) - { - delete m_pTimeoutTimer; - m_pTimeoutTimer = 0; - } - - if(m_bUseTimeout) - { - m_pTimeoutTimer = new QTimer(); - connect(m_pTimeoutTimer,SIGNAL(timeout()),this,SLOT(connectionTimedOut())); - m_pTimeoutTimer->setSingleShot(true); - m_pTimeoutTimer->setInterval(KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) * 1000); - m_pTimeoutTimer->start(); - } - - // and wait for connect - emit inProgress(); -} - - -void KviDccMarshal::snActivated(int) -{ - if(m_pTimeoutTimer) - { - delete m_pTimeoutTimer; - m_pTimeoutTimer = 0; - } -#ifdef COMPILE_IPV6_SUPPORT - struct sockaddr_in6 hostSockAddr6; -#endif - struct sockaddr_in hostSockAddr; - - int size = sizeof(hostSockAddr); - struct sockaddr * addr = (struct sockaddr *)&hostSockAddr; - -#ifdef COMPILE_IPV6_SUPPORT - if(m_bIPv6) - { - addr = (struct sockaddr *)&hostSockAddr6; - size = sizeof(hostSockAddr6); - } -#endif - - if(m_bOutgoing) - { - // outgoing connection (we have called connect()) - // Check for errors... - int sockError; - int iSize=sizeof(int); - if(!kvi_socket_getsockopt(m_fd,SOL_SOCKET,SO_ERROR,(void *)&sockError,&iSize))sockError = -1; - if(sockError != 0) - { - //failed - if(sockError > 0)sockError = KviError::translateSystemError(sockError); - else sockError = KviError::UnknownError; //Error 0 ? - reset(); - emit error(sockError); - return; - } - //Succesfully connected... - delete m_pSn; - m_pSn = 0; - // get the local address - if(!kvi_socket_getsockname(m_fd,addr,&size)) - { - m_szSecondaryIp = "localhost"; - m_szSecondaryPort = __tr2qs_ctx("unknown","dcc"); - } else { -#ifdef COMPILE_IPV6_SUPPORT - if(m_bIPv6) - { - m_szSecondaryPort.setNum(ntohs(((struct sockaddr_in6 *)addr)->sin6_port)); - if(!KviNetUtils::binaryIpToStringIp_V6(((struct sockaddr_in6 *)addr)->sin6_addr,m_szSecondaryIp)) - m_szSecondaryIp = "localhost"; - } else { -#endif - m_szSecondaryPort.setNum(ntohs(((struct sockaddr_in *)addr)->sin_port)); - if(!KviNetUtils::binaryIpToStringIp(((struct sockaddr_in *)addr)->sin_addr,m_szSecondaryIp)) - m_szSecondaryIp = "localhost"; -#ifdef COMPILE_IPV6_SUPPORT - } -#endif - } - } else { - // Incoming connection - int newsock = kvi_socket_accept(m_fd,addr,&size); - if(newsock != KVI_INVALID_SOCKET) - { - // Connected - delete m_pSn; - m_pSn = 0; -#ifdef COMPILE_IPV6_SUPPORT - if(m_bIPv6) - { - m_szSecondaryPort.setNum(ntohs(((struct sockaddr_in6 *)addr)->sin6_port)); - if(!KviNetUtils::binaryIpToStringIp_V6(((struct sockaddr_in6 *)addr)->sin6_addr,m_szSecondaryIp)) - m_szSecondaryIp = __tr2qs_ctx("unknown","dcc"); - } else { -#endif - m_szSecondaryPort.setNum(ntohs(((struct sockaddr_in *)addr)->sin_port)); - if(!KviNetUtils::binaryIpToStringIp(((struct sockaddr_in *)addr)->sin_addr,m_szSecondaryIp)) - m_szSecondaryIp = __tr2qs_ctx("unknown","dcc"); -#ifdef COMPILE_IPV6_SUPPORT - } -#endif - kvi_socket_close(m_fd); - m_fd = newsock; - if(!kvi_socket_setNonBlocking(m_fd)) - { - reset(); - emit error(KviError::AsyncSocketFailed); - return; - } - - } else { - // Huh ?.. wait for the next notifier call - return; - } - } - -#ifdef COMPILE_SSL_SUPPORT - // SSL Handshake needed ? - if(m_bUseSSL) - { - m_pSSL = KviSSLMaster::allocSSL(m_pOutputContext->dccMarshalOutputWindow(),m_fd,m_bOutgoing ? KviSSL::Client : KviSSL::Server,m_pOutputContext->dccMarshalOutputContextString()); - - if(m_pSSL) - { - emit startingSSLHandshake(); - doSSLHandshake(0); - } else { - reset(); - emit error(KviError::SSLError); - } - return; - } -#endif - - emit connected(); -} - -void KviDccMarshal::doSSLHandshake(int) -{ -#ifdef COMPILE_SSL_SUPPORT -// qDebug("DO SSL HANDSHAKE"); - if(m_pSn) - { - delete m_pSn; - m_pSn = 0; - } - - if(!m_pSSL) - { - qDebug("Ops... I've lost the SSL class ?"); - reset(); - emit error(KviError::InternalError); - return; // ops ? - } - - KviSSL::Result r = m_bOutgoing ? m_pSSL->connect() : m_pSSL->accept(); - - switch(r) - { - case KviSSL::Success: - // done! -// qDebug("EMITTING CONNECTED"); - emit connected(); -// qDebug("CONNECTED EMITTED"); - break; - case KviSSL::WantRead: - m_pSn = new QSocketNotifier((int)m_fd,QSocketNotifier::Read); - QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(doSSLHandshake(int))); - m_pSn->setEnabled(true); - break; - case KviSSL::WantWrite: - m_pSn = new QSocketNotifier((int)m_fd,QSocketNotifier::Write); - QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(doSSLHandshake(int))); - m_pSn->setEnabled(true); - break; - case KviSSL::RemoteEndClosedConnection: - reset(); - emit error(KviError::RemoteEndClosedConnection); - break; - case KviSSL::SyscallError: - { - // syscall problem - int err = kvi_socket_error(); - if(kvi_socket_recoverableError(err)) - { - // can recover ? (EAGAIN, EINTR ?) - m_pSn = new QSocketNotifier((int)m_fd,QSocketNotifier::Write); - QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(doSSLHandshake(int))); - m_pSn->setEnabled(true); - return; - } else { - // Declare problems :) - reset(); - emit error(err ? KviError::translateSystemError(err) : KviError::UnknownError); - } - } - break; - default: - { - KviCString buffer; - while(m_pSSL->getLastErrorString(buffer))emit sslError(buffer.ptr()); - reset(); - emit error(KviError::SSLError); - } - break; - } -#else //!COMPILE_SSL_SUPPORT - qDebug("Ops.. ssl handshake without ssl support!...aborting!"); - exit(-1); -#endif //!COMPILE_SSL_SUPPORT -} - -void KviDccMarshal::abort() -{ - reset(); -} - -void KviDccMarshal::connectionTimedOut() -{ - reset(); - emit error(KviError::ConnectionTimedOut); -} - - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_marshal.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/dcc/marshal.h b/src/modules/dcc/marshal.h deleted file mode 100644 index aec02107e..000000000 --- a/src/modules/dcc/marshal.h +++ /dev/null @@ -1,116 +0,0 @@ -#ifndef _MARSHAL_H_ -#define _MARSHAL_H_ -//============================================================================= -// -// File marshal.h -// Creation date : Sun Sep 17 2000 10:44:20 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "KviCString.h" -#include "KviError.h" -#include "kvi_sockettype.h" -#include "kvi_inttypes.h" - -#include -#include -#include - -class KviWindow; -class KviDccMarshal; - -#ifdef COMPILE_SSL_SUPPORT - #include "KviSSLMaster.h" -#endif - - -class KviDccMarshalOutputContext -{ - friend class KviDccMarshal; -public: - KviDccMarshalOutputContext(){}; - virtual ~KviDccMarshalOutputContext(){}; -protected: - virtual KviWindow * dccMarshalOutputWindow() = 0; - virtual const char * dccMarshalOutputContextString() = 0; -}; - -class KviDccMarshal : public QObject -{ - Q_OBJECT -public: - KviDccMarshal(KviDccMarshalOutputContext * ctx); - ~KviDccMarshal(); -protected: - // DCC DESCRIPTOR - QString m_szIp; // Dcc initiator ip address (the one that listens) - QString m_szPort; // Dcc initiator port (the one that listens) - // other info - bool m_bIPv6; // Dcc mode - kvi_u32_t m_uPort; // Dcc initiator port - bool m_bOutgoing; // true if WE have connected to the remote host (so m_szIp is the remote host ip) - QString m_szSecondaryIp; // Ip of the client that has connected to the remote host - QString m_szSecondaryPort; // Port of the client that has connected to the remote host - // internals - kvi_socket_t m_fd; // socket - QSocketNotifier * m_pSn; - bool m_bUseTimeout; - QTimer * m_pTimeoutTimer; -#ifdef COMPILE_SSL_SUPPORT - KviSSL * m_pSSL; - bool m_bUseSSL; -#endif - KviDccMarshalOutputContext * m_pOutputContext; -public: - const QString & dccIp() const { return m_szIp; }; - const QString & dccPort() const { return m_szPort; }; - const QString & localIp() const { return m_bOutgoing ? m_szSecondaryIp : m_szIp; }; - const QString & localPort() const { return m_bOutgoing ? m_szSecondaryPort : m_szPort; }; - const QString & remoteIp() const { return m_bOutgoing ? m_szIp : m_szSecondaryIp; }; - const QString & remotePort() const { return m_bOutgoing ? m_szPort : m_szSecondaryPort; }; - KviError::Code dccListen(const QString &ip,const QString &port,bool bUseTimeout,bool bUseSSL = false); - KviError::Code dccConnect(const char * ip,const char * port,bool bUseTimeout,bool bUseSSL = false); - kvi_socket_t releaseSocket(); -#ifdef COMPILE_SSL_SUPPORT - KviSSL * releaseSSL(); -#endif - void abort(); -private: - void reset(); -//#ifdef COMPILE_SSL_SUPPORT -// bool trySSLCertificate(); -//#endif -private slots: - void doSSLHandshake(int); -// void doListenSSLHandshake(); - void snActivated(int); - void connectionTimedOut(); - void doListen(); - void doConnect(); -signals: - void startingSSLHandshake(); - void sslError(const char * msg); - void connected(); - void inProgress(); - void error(int); -}; - - -#endif //_MARSHAL_H_ diff --git a/src/modules/dcc/requests.cpp b/src/modules/dcc/requests.cpp index 5dbe4cea5..232c7a441 100644 --- a/src/modules/dcc/requests.cpp +++ b/src/modules/dcc/requests.cpp @@ -24,16 +24,16 @@ #define _KVI_DEBUG_CHECK_RANGE_ -#include "gsmcodec.h" -#include "broker.h" +#include "DccVoiceGsmCodec.h" +#include "DccBroker.h" #ifndef COMPILE_DISABLE_DCC_VIDEO - #include "video.h" + #include "DccVideoWindow.h" #endif -#include "voice.h" -#include "utils.h" -#include "send.h" +#include "DccVoiceWindow.h" +#include "DccUtils.h" +#include "DccFileTransfer.h" #include "kvi_debug.h" #include "kvi_settings.h" @@ -59,13 +59,13 @@ #ifdef COMPILE_ON_WINDOWS // Ugly Windoze compiler... - #include "dialogs.h" + #include "DccDialog.h" #endif //#warning "KviOption_boolIgnoreDccChat and other types too" extern KVIRC_API KviSharedFilesManager * g_pSharedFilesManager; -extern KviDccBroker * g_pDccBroker; +extern DccBroker * g_pDccBroker; static void dcc_module_reply_errmsg(KviDccRequest * dcc,const QString& errText) { @@ -95,7 +95,7 @@ static bool dcc_module_check_concurrent_transfers_limit(KviDccRequest * dcc) { if(KVI_OPTION_UINT(KviOption_uintMaxDccSendTransfers) > 0) { - unsigned int uTransfers = KviDccFileTransfer::runningTransfersCount(); + unsigned int uTransfers = DccFileTransfer::runningTransfersCount(); if(uTransfers >= KVI_OPTION_UINT(KviOption_uintMaxDccSendTransfers)) { QString szError; @@ -131,7 +131,7 @@ static bool dcc_module_check_limits(KviDccRequest * dcc) return true; } -static void dcc_fill_local_nick_user_host(KviDccDescriptor * d,KviDccRequest * dcc) +static void dcc_fill_local_nick_user_host(DccDescriptor * d,KviDccRequest * dcc) { if(dcc->pConsole->connection()) { @@ -145,7 +145,7 @@ static void dcc_fill_local_nick_user_host(KviDccDescriptor * d,KviDccRequest * d } } -static void dcc_module_set_dcc_type(KviDccDescriptor * d,const char * szBaseType) +static void dcc_module_set_dcc_type(DccDescriptor * d,const char * szBaseType) { d->szType = szBaseType; #ifdef COMPILE_SSL_SUPPORT @@ -283,7 +283,7 @@ static void dccModuleParseDccChat(KviDccRequest *dcc) } #endif //!COMPILE_SSL_SUPPORT - KviDccDescriptor * d = new KviDccDescriptor(dcc->pConsole); + DccDescriptor * d = new DccDescriptor(dcc->pConsole); d->szNick = dcc->ctcpMsg->pSource->nick(); d->szUser = dcc->ctcpMsg->pSource->user(); @@ -489,7 +489,7 @@ static void dccModuleParseDccSend(KviDccRequest *dcc) } #endif //!COMPILE_SSL_SUPPORT - KviDccDescriptor * d = new KviDccDescriptor(dcc->pConsole); + DccDescriptor * d = new DccDescriptor(dcc->pConsole); d->szNick = dcc->ctcpMsg->pSource->nick(); d->szUser = dcc->ctcpMsg->pSource->user(); d->szHost = dcc->ctcpMsg->pSource->host(); @@ -658,7 +658,7 @@ static void dccModuleParseDccRecv(KviDccRequest * dcc) // ok...we have requested this send // #warning "Maybe remove this file offer now ?" - KviDccDescriptor * d = new KviDccDescriptor(dcc->pConsole); + DccDescriptor * d = new DccDescriptor(dcc->pConsole); d->szNick = dcc->ctcpMsg->pSource->nick(); d->szUser = dcc->ctcpMsg->pSource->user(); @@ -781,7 +781,7 @@ static void dccModuleParseDccRSend(KviDccRequest *dcc) //#warning "When behind a firewall, we should reply an error message and avoid setting up the listening connection" - KviDccDescriptor * d = new KviDccDescriptor(dcc->pConsole); + DccDescriptor * d = new DccDescriptor(dcc->pConsole); d->szNick = dcc->ctcpMsg->pSource->nick(); d->szUser = dcc->ctcpMsg->pSource->user(); d->szHost = dcc->ctcpMsg->pSource->host(); @@ -929,7 +929,7 @@ static void dccModuleParseDccGet(KviDccRequest *dcc) } - KviDccDescriptor * d = new KviDccDescriptor(dcc->pConsole); + DccDescriptor * d = new DccDescriptor(dcc->pConsole); d->szNick = dcc->ctcpMsg->pSource->nick(); d->szLocalFileName = o->absFilePath(); d->szUser = dcc->ctcpMsg->pSource->user(); @@ -1034,7 +1034,7 @@ static void dccModuleParseDccVoice(KviDccRequest *dcc) } - KviDccDescriptor * d = new KviDccDescriptor(dcc->pConsole); + DccDescriptor * d = new DccDescriptor(dcc->pConsole); d->szNick = dcc->ctcpMsg->pSource->nick(); d->szUser = dcc->ctcpMsg->pSource->user(); d->szHost = dcc->ctcpMsg->pSource->host(); @@ -1108,7 +1108,7 @@ static void dccModuleParseDccVideo(KviDccRequest *dcc) // } - KviDccDescriptor * d = new KviDccDescriptor(dcc->pConsole); + DccDescriptor * d = new DccDescriptor(dcc->pConsole); d->szNick = dcc->ctcpMsg->pSource->nick(); d->szUser = dcc->ctcpMsg->pSource->user(); d->szHost = dcc->ctcpMsg->pSource->host(); @@ -1158,7 +1158,7 @@ static void dccModuleParseDccCanvas(KviDccRequest *dcc) // } // } #ifdef COMPILE_DCC_CANVAS - KviDccDescriptor * d = new KviDccDescriptor(dcc->pConsole); + DccDescriptor * d = new DccDescriptor(dcc->pConsole); d->szNick = dcc->ctcpMsg->pSource->nick(); d->szUser = dcc->ctcpMsg->pSource->username(); d->szHost = dcc->ctcpMsg->pSource->host(); diff --git a/src/modules/dcc/send.cpp b/src/modules/dcc/send.cpp deleted file mode 100644 index b4c1f0cde..000000000 --- a/src/modules/dcc/send.cpp +++ /dev/null @@ -1,2248 +0,0 @@ -//============================================================================= -// -// File : send.cpp -// Creation date : Tue Sep 20 09 2000 15:14:14 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#define _KVI_DEBUG_CHECK_RANGE_ - -#include "send.h" -#include "broker.h" -#include "marshal.h" -#include "broker.h" -#include "window.h" - -#include "kvi_debug.h" -#include "KviApplication.h" -#include "KviOptions.h" -#include "KviIrcView.h" -#include "KviIconManager.h" -#include "KviLocale.h" -#include "KviError.h" -#include "kvi_out.h" -#include "KviNetUtils.h" -#include "KviConsoleWindow.h" -#include "KviMainWindow.h" -#include "KviMemory.h" -#include "KviMemory.h" -#include "KviThread.h" -#include "KviIrcSocket.h" -#include "KviMediaManager.h" -#include "kvi_socket.h" -#include "KviKvsEventTriggers.h" -#include "KviParameterList.h" -#include "KviIrcConnection.h" -#include "KviIrcConnectionUserInfo.h" -#include "KviIrcServerParser.h" -#include "KviKvsScript.h" - -#ifdef COMPILE_ON_WINDOWS - // Ugly Windoze compiler... - #include "dialogs.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS 3000 -#define INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS 3 - -// This limit, when multiplied by INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS -// must fit in 31 bits (0x7fffffff)! (because of data size limits) -#define MAX_DCC_BANDWIDTH_LIMIT 0x1fffffff - -// FIXME: The events OnDCCConnect etc are in wrong places here...! - -extern KviDccBroker * g_pDccBroker; - -extern KVIRC_API KviMediaManager * g_pMediaManager; // KviApplication.cpp - - -static KviPointerList * g_pDccFileTransfers = 0; -static QPixmap * g_pDccFileTransferIcon = 0; - -//#warning "The events that have a KviCString data pointer should become real classes, that take care of deleting the data pointer!" -//#warning "Otherwise, when left undispatched we will be leaking memory (event class destroyed but not the data ptr)" - -KviDccRecvThread::KviDccRecvThread(QObject * par,kvi_socket_t fd,KviDccRecvThreadOptions * opt) -: KviDccThread(par,fd) -{ - m_pOpt = opt; - m_uAverageSpeed = 0; - m_uInstantSpeed = 0; - m_uFilePosition = 0; - - m_uTotalReceivedBytes = 0; - m_uInstantReceivedBytes = 0; - m_pFile = 0; - m_pTimeInterval = new KviMSecTimeInterval(); - m_uStartTime = 0; - m_uInstantSpeedInterval = 0; -} - -KviDccRecvThread::~KviDccRecvThread() -{ - if(m_pOpt)delete m_pOpt; - if(m_pFile)delete m_pFile; - delete m_pTimeInterval; -} - -bool KviDccRecvThread::sendAck(int filePos) -{ - quint32 size = htonl(filePos & 0xffffffff); - int iRet=0; -#ifdef COMPILE_SSL_SUPPORT - if(m_pSSL) - { - iRet = m_pSSL->write((char*)(&size),4); - } else { -#endif - iRet = kvi_socket_send(m_fd,(void *)(&size),4); -#ifdef COMPILE_SSL_SUPPORT - } -#endif - - if(iRet != 4) - { - postErrorEvent(KviError::AcknowledgeError); - return false; - } - return true; -} - -void KviDccRecvThread::updateStats() -{ - m_uInstantSpeedInterval += m_pTimeInterval->mark(); - unsigned long uCurTime = m_pTimeInterval->secondsCounter(); - - m_pMutex->lock(); - unsigned long uElapsedTime = uCurTime - m_uStartTime; - if(uElapsedTime < 1)uElapsedTime = 1; - - m_uFilePosition = m_pFile->pos(); - m_uAverageSpeed = m_uTotalReceivedBytes / uElapsedTime; - - if(m_uInstantSpeedInterval > INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS) - { - unsigned int uMSecsOfTheNextInterval = 0; - if(m_uInstantSpeedInterval < (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS + (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS / 2))) - uMSecsOfTheNextInterval = m_uInstantSpeedInterval - INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS; - m_uInstantSpeed = (m_uInstantReceivedBytes * 1000) / m_uInstantSpeedInterval; - m_uInstantReceivedBytes = 0; - m_uInstantSpeedInterval = uMSecsOfTheNextInterval; - } else { - if(uElapsedTime <= INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS) - m_uInstantSpeed = m_uAverageSpeed; - } - m_pMutex->unlock(); -} - -void KviDccRecvThread::postMessageEvent(const char * m) -{ - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_MESSAGE); - e->setData(new KviCString(m)); - postEvent(parent(),e); -} - -// FIXME: This stuff should be somewhat related to the 1448 bytes TCP basic packet size -#define KVI_DCC_RECV_BLOCK_SIZE 8192 -#define KVI_DCC_RECV_75PERCENTOF_BLOCK_SIZE 6150 - -void KviDccRecvThread::run() -{ - // take care of sleeping a bit if we can't read stuff - // so we don't hog the CPU too much... - int iFailedSelects = 0; - // take care of sleeping a bit if we get a lot of short reads - // so we don't hog the CPU too much... - int iShortReadQuantifier = 0; - // the algorithm is as follows: - // attempt to read KVI_DCC_RECV_BLOCK_SIZE bytes - // iShortReadQuantifier += ((KVI_DCC_RECV_75PERCENT_OF_BLOCK_SIZE - realReadedBytes) / 42); - // thus we gain points if we read less than 75% of the requested size - // and we loose points otherwise - // there are nearly 24 points per KB - // if(iShortReadQuantifier > 10) - // msleep(iShortReadQuantifier); - // also never sleep more than 500 msecs since it will - // rise our exit latency too much - - m_pTimeInterval->mark(); - m_pMutex->lock(); - m_uStartTime = m_pTimeInterval->secondsCounter(); - m_pMutex->unlock(); - - int iProbableTerminationTime = 0; - - m_pFile = new QFile(QString::fromUtf8(m_pOpt->szFileName.ptr())); - - if(m_pOpt->bResume) - { - if(!m_pFile->open(QIODevice::WriteOnly | QIODevice::Append)) - { - postErrorEvent(KviError::CantOpenFileForAppending); - goto exit_dcc; - } // else pFile is already at end - } else { - if(!m_pFile->open(QIODevice::WriteOnly)) - { - postErrorEvent(KviError::CantOpenFileForWriting); - goto exit_dcc; - } - } - - if(m_pOpt->bSendZeroAck && (!m_pOpt->bNoAcks)) - { - if(!sendAck(m_pFile->pos()))goto exit_dcc; - } - - for(;;) - { - // Dequeue events - while(KviThreadEvent * e = dequeueEvent()) - { - if(e->id() == KVI_THREAD_EVENT_TERMINATE) - { - delete e; - goto exit_dcc; - } else { - // Other events are senseless to us - delete e; - } - } - - bool bCanRead; - bool bDummy; - - if(kvi_select(m_fd,&bCanRead,&bDummy,15000)) - { - // reset sleep time - - if(bCanRead) - { - iFailedSelects = 0; - - // Read a data block - char buffer[KVI_DCC_RECV_BLOCK_SIZE]; - - m_pMutex->lock(); // FIXME: how to remove this lock ? - unsigned int uMaxPossible = (m_pOpt->uMaxBandwidth < MAX_DCC_BANDWIDTH_LIMIT) ? m_pOpt->uMaxBandwidth * INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS : MAX_DCC_BANDWIDTH_LIMIT * INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS; - m_pMutex->unlock(); - unsigned int uToRead = uMaxPossible > m_uInstantReceivedBytes ? uMaxPossible - m_uInstantReceivedBytes : 0; - if(uToRead > KVI_DCC_RECV_BLOCK_SIZE)uToRead = KVI_DCC_RECV_BLOCK_SIZE; - - if(uToRead > 0) - { - int readLen; -#ifdef COMPILE_SSL_SUPPORT - if(m_pSSL) - { - readLen = m_pSSL->read(buffer,uToRead); - } else { -#endif - readLen = kvi_socket_recv(m_fd,buffer,uToRead); -#ifdef COMPILE_SSL_SUPPORT - } -#endif - - if(readLen > 0) - { - // Readed something useful...write back - if(((uint)(readLen + m_pFile->pos())) > m_pOpt->uTotalFileSize) - { - postMessageEvent(__tr_no_lookup_ctx("WARNING: The peer is sending garbage data past the end of the file","dcc")); - postMessageEvent(__tr_no_lookup_ctx("WARNING: Ignoring data past the declared end of file and closing the connection","dcc")); - - readLen = m_pOpt->uTotalFileSize - m_pFile->pos(); - if(readLen > 0) - { - if(m_pFile->write(buffer,readLen) != readLen) - postErrorEvent(KviError::FileIOError); - } - break; - - } else { - if(m_pFile->write(buffer,readLen) != readLen) - { - postErrorEvent(KviError::FileIOError); - break; - } - } - - // Update stats - m_uTotalReceivedBytes += readLen; - m_uInstantReceivedBytes += readLen; - - updateStats(); - // Now send the ack - if(m_pOpt->bNoAcks) - { - // No acks... - // Interrupt if the whole file has been received - if(m_pOpt->uTotalFileSize > 0) - { - if((quint64)m_pFile->pos() == m_pOpt->uTotalFileSize) - { - // Received the whole file...die - KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS); - postEvent(parent(),e); - break; - } - } - } else { - // Must send the ack... the peer must close the connection - if(!sendAck(m_pFile->pos()))break; - } - - // now take care of short reads - iShortReadQuantifier += ((KVI_DCC_RECV_75PERCENTOF_BLOCK_SIZE - readLen) / 42); - if(iShortReadQuantifier > 10) - { - // we're having short reads.. sleep a while - // but don't allow it to go too high: 0.45 sec is really a lot - if(iShortReadQuantifier > 500) - iShortReadQuantifier = 500; - msleep(iShortReadQuantifier); - } else { - // don't allow it to go too low - if(iShortReadQuantifier < -500) - iShortReadQuantifier = -500; - } - - } else { - updateStats(); - // Read problem... - -#ifdef COMPILE_SSL_SUPPORT - if(m_pSSL) - { - // ssl error....? - switch(m_pSSL->getProtocolError(readLen)) - { - case KviSSL::ZeroReturn: - readLen = 0; - break; - case KviSSL::WantRead: - case KviSSL::WantWrite: - // hmmm... - break; - case KviSSL::SyscallError: - { - int iE = m_pSSL->getLastError(true); - if(iE != 0) - { - raiseSSLError(); - postErrorEvent(KviError::SSLError); - goto exit_dcc; - } - } - break; - case KviSSL::SSLError: - { - raiseSSLError(); - postErrorEvent(KviError::SSLError); - goto exit_dcc; - } - break; - default: - // Raise unknown SSL ERROR - postErrorEvent(KviError::SSLError); - goto exit_dcc; - break; - } - } -#endif - - if(readLen == 0) - { - // read EOF.. - if(((quint64)m_pFile->pos() == m_pOpt->uTotalFileSize) || (m_pOpt->uTotalFileSize == 0)) - { - // success if we got the whole file or if we don't know the file size (we trust the peer) - KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS); - postEvent(parent(),e); - break; - } - } - if(!handleInvalidSocketRead(readLen))break; - } - } else { - updateStats(); - - // reached the bandwidth limit: slow down a bit - if(m_uInstantSpeedInterval < (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS - 100)) - msleep(100); - else if(m_uInstantSpeedInterval < (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS - 20)) - msleep(20); - } - } else { - // Can't read stuff (can just write) - updateStats(); - - // sleep up to 300 msecs (if data arrives...we want low exit latency here) - if(iFailedSelects < 100)iFailedSelects++; - updateStats(); - if(iFailedSelects > 3) - msleep(3 * iFailedSelects); - - if((quint64)m_pFile->pos() == m_pOpt->uTotalFileSize) - { - // Wait for the peer to close the connection - if(iProbableTerminationTime == 0) - { - iProbableTerminationTime = (int)kvi_unixTime(); - m_pFile->flush(); - postMessageEvent(__tr_no_lookup_ctx("Data transfer terminated, waiting 30 seconds for the peer to close the connection...","dcc")); - // FIXME: Close the file ? - } else { - int iDiff = (((int)kvi_unixTime()) - iProbableTerminationTime); - if(iDiff > 30) - { - // success if we got the whole file or if we don't know the file size (we trust the peer) - postMessageEvent(__tr_no_lookup_ctx("Data transfer was terminated 30 seconds ago, closing the connection","dcc")); - KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS); - postEvent(parent(),e); - break; - } - } - } - } - // include the artificial delay if needed - if(m_pOpt->iIdleStepLengthInMSec > 0) - msleep(m_pOpt->iIdleStepLengthInMSec); - } else { - // sleep up to 200 msecs (if data arrives...we want low exit latency here) - if(iFailedSelects < 100)iFailedSelects++; - updateStats(); - if(iFailedSelects > 3) - msleep(2 * iFailedSelects); - } - } - -exit_dcc: - if(m_pFile) - { - m_pFile->close(); - delete m_pFile; - m_pFile = 0; - } - -#ifdef COMPILE_SSL_SUPPORT - if(m_pSSL) - { - KviSSLMaster::freeSSL(m_pSSL); - m_pSSL = 0; - } -#endif - - kvi_socket_close(m_fd); - m_fd = KVI_INVALID_SOCKET; -} - -void KviDccRecvThread::initGetInfo() -{ - m_pMutex->lock(); -} - -void KviDccRecvThread::doneGetInfo() -{ - m_pMutex->unlock(); -} - -KviDccSendThread::KviDccSendThread(QObject * par,kvi_socket_t fd,KviDccSendThreadOptions * opt) -: KviDccThread(par,fd) -{ - m_pOpt = opt; - // stats - m_uAverageSpeed = 0; - m_uInstantSpeed = 0; - m_uFilePosition = 0; - m_uTotalSentBytes = 0; - m_pTimeInterval = new KviMSecTimeInterval(); - m_uStartTime = 0; - m_uInstantSpeedInterval = 0; -} - -KviDccSendThread::~KviDccSendThread() -{ - if(m_pOpt)delete m_pOpt; - delete m_pTimeInterval; -} - -void KviDccSendThread::updateStats() -{ - m_uInstantSpeedInterval += m_pTimeInterval->mark(); - - m_pMutex->lock(); - unsigned long uElapsedTime = m_pTimeInterval->secondsCounter() - m_uStartTime; - if(uElapsedTime < 1)uElapsedTime = 1; - - if(m_pOpt->bNoAcks) - { - // There are no acks : the avg bandwidth is based on the sent bytes - m_uAverageSpeed = m_uTotalSentBytes / uElapsedTime; - } else { - // acknowledges : we compute the avg bandwidth based on the acks we receive - m_uAverageSpeed = (m_uAckedBytes - m_pOpt->uStartPosition) / uElapsedTime; - } - - if(m_uInstantSpeedInterval >= INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS) - { - // we often overcount the time interval of 10-20 msecs - // and thus our bandwidth is used less than requested. - // for this reason we try to account the time in excess - // to the next period in order to balance the bandwidth usage. - unsigned long uMSecsOfNextPeriodUsed = 0; - if(m_uInstantSpeedInterval > INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS) - { - if(m_uInstantSpeedInterval < (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS + (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS / 2))) - { - uMSecsOfNextPeriodUsed = m_uInstantSpeedInterval - INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS; - m_uInstantSpeedInterval = INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS; - } - // else we have been delayed for a time comparable to a period - // and thus we can't recover the bandwidth... let it go as it does... - } - m_uInstantSpeed = (m_uInstantSentBytes * 1000) / m_uInstantSpeedInterval; - m_uInstantSpeedInterval = uMSecsOfNextPeriodUsed; - m_uInstantSentBytes = 0; - } else { - if(uElapsedTime <= INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS) - m_uInstantSpeed = m_uAverageSpeed; - } - m_pMutex->unlock(); -} - -union _ack_buffer { - char cAckBuffer[4]; - quint32 i32AckBuffer; -}; - -void KviDccSendThread::run() -{ - m_pTimeInterval->mark(); - m_pMutex->lock(); - m_uStartTime = m_pTimeInterval->secondsCounter(); - m_pMutex->unlock(); - - m_uTotalSentBytes = 0; - m_uInstantSentBytes = 0; - int iFailedSelects = 0; - _ack_buffer ackbuffer; - int iBytesInAckBuffer = 0; - quint32 uLastAck = 0; - quint64 uTotLastAck = 0; - bool bAckHack = false; - int iAckHackRounds = 0; - - if(m_pOpt->iPacketSize < 32)m_pOpt->iPacketSize = 32; - char * buffer = (char *)KviMemory::allocate(m_pOpt->iPacketSize * sizeof(char)); - - QFile * pFile = new QFile(QString::fromUtf8(m_pOpt->szFileName.ptr())); - - if(!pFile->open(QIODevice::ReadOnly)) - { - postErrorEvent(KviError::CantOpenFileForReading); - goto exit_dcc; - } - - if(pFile->size() < 1) - { - postErrorEvent(KviError::CantSendAZeroSizeFile); - goto exit_dcc; - } - - if(pFile->size() >= 0xffffffff) - { - //dcc acks support only files up to 4GiB - bAckHack=true; - } - - if(m_pOpt->uStartPosition > 0) - { - // seek - if(!(pFile->seek(m_pOpt->uStartPosition))) - { - postErrorEvent(KviError::FileIOError); - goto exit_dcc; - } - } - - uLastAck = m_pOpt->uStartPosition; - - for(;;) - { - // Dequeue events - while(KviThreadEvent * e = dequeueEvent()) - { - if(e->id() == KVI_THREAD_EVENT_TERMINATE) - { - delete e; - goto exit_dcc; - } else { - // Other events are senseless to us - delete e; - } - } - - bool bCanRead; - bool bCanWrite; - - if(kvi_select(m_fd,&bCanRead,&bCanWrite,15000)) - { - // reset the sleep time - iFailedSelects = 0; - if(bCanRead) - { - if(!m_pOpt->bNoAcks) - { - int iAckBytesToRead = 4 - iBytesInAckBuffer; - - int readLen; -#ifdef COMPILE_SSL_SUPPORT - if(m_pSSL) - { - readLen = m_pSSL->read((ackbuffer.cAckBuffer + iBytesInAckBuffer),iAckBytesToRead); - } else { -#endif - readLen = kvi_socket_recv(m_fd,(ackbuffer.cAckBuffer + iBytesInAckBuffer),iAckBytesToRead); -#ifdef COMPILE_SSL_SUPPORT - } -#endif - - if(readLen > 0) - { - iBytesInAckBuffer += readLen; - if(iBytesInAckBuffer == 4) - { - quint32 iNewAck = ntohl(ackbuffer.i32AckBuffer); - if(iNewAck > pFile->pos()) - { - // the peer is drunk or is trying to fool us - postErrorEvent(KviError::AcknowledgeError); - break; - } - if(iNewAck < uLastAck) - { - if(bAckHack) - { - //we reached the 4gb ack limit - iAckHackRounds++; - } else { - // the peer is drunk or is trying to fool us - postErrorEvent(KviError::AcknowledgeError); - break; - } - } - uLastAck = iNewAck; - if(bAckHack) - { - uTotLastAck = (iAckHackRounds*4u*1024u*1024u*1024u) + iNewAck; - } else { - - uTotLastAck = iNewAck; - } - iBytesInAckBuffer = 0; - } - } else { -#ifdef COMPILE_SSL_SUPPORT - if(m_pSSL) - { - // ssl error....? - switch(m_pSSL->getProtocolError(readLen)) - { - case KviSSL::ZeroReturn: - readLen = 0; - break; - case KviSSL::WantRead: - case KviSSL::WantWrite: - // hmmm... - break; - case KviSSL::SyscallError: - { - int iE = m_pSSL->getLastError(true); - if(iE != 0) - { - raiseSSLError(); - postErrorEvent(KviError::SSLError); - goto exit_dcc; - } - } - break; - case KviSSL::SSLError: - { - raiseSSLError(); - postErrorEvent(KviError::SSLError); - goto exit_dcc; - } - break; - default: - // Raise unknown SSL ERROR - postErrorEvent(KviError::SSLError); - goto exit_dcc; - break; - } - } -#endif - - if(!handleInvalidSocketRead(readLen))break; - } - - // update stats - m_pMutex->lock(); // is this really necessary ? - m_uAckedBytes = uTotLastAck; - m_pMutex->unlock(); - - if(uLastAck >= (quint64)pFile->size()) - { - KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS); - postEvent(parent(),e); - break; - } - } else { - // No acknowledges - if(m_pOpt->bIsTdcc) - { - // We expect the remote end to close the connection when the whole file has been sent - if(pFile->atEnd()) - { - int iAck; - int readLen; -#ifdef COMPILE_SSL_SUPPORT - if(m_pSSL) - { - readLen = m_pSSL->read((char*)&iAck,4); - } else { -#endif - readLen = kvi_socket_recv(m_fd,(char*)&iAck,4); -#ifdef COMPILE_SSL_SUPPORT - } -#endif - if(readLen == 0) - { - // done...success - updateStats(); - KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS); - postEvent(parent(),e); - break; - } else { - if(readLen < 0) - { -#ifdef COMPILE_SSL_SUPPORT - if(m_pSSL) - { - // ssl error....? - switch(m_pSSL->getProtocolError(readLen)) - { - case KviSSL::ZeroReturn: - readLen = 0; - break; - case KviSSL::WantRead: - case KviSSL::WantWrite: - // hmmm... - break; - case KviSSL::SyscallError: - { - int iE = m_pSSL->getLastError(true); - if(iE != 0) - { - raiseSSLError(); - postErrorEvent(KviError::SSLError); - goto exit_dcc; - } - } - break; - case KviSSL::SSLError: - { - raiseSSLError(); - postErrorEvent(KviError::SSLError); - goto exit_dcc; - } - break; - default: - // Raise unknown SSL ERROR - postErrorEvent(KviError::SSLError); - goto exit_dcc; - break; - } - } -#endif - - if(!handleInvalidSocketRead(readLen))break; - } else { - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_MESSAGE); - e->setData(new KviCString(__tr2qs_ctx("WARNING: Received data in a DCC TSEND, there should be no acknowledges","dcc"))); - postEvent(parent(),e); - } - } - } - } - } - } - if(bCanWrite) - { - if(!pFile->atEnd()) - { - if(m_pOpt->bFastSend || m_pOpt->bNoAcks || (uLastAck == (quint64)pFile->pos())) - { - // maximum readable size - qint64 toRead = pFile->size() - pFile->pos(); - // the max number of bytes we can send in this interval (bandwidth limit) - m_pMutex->lock(); // FIXME: how to remove this lock ? - uint uMaxPossible = m_pOpt->uMaxBandwidth < MAX_DCC_BANDWIDTH_LIMIT ? m_pOpt->uMaxBandwidth * INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS : MAX_DCC_BANDWIDTH_LIMIT * INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS; - m_pMutex->unlock(); - if(uMaxPossible < m_uInstantSentBytes)toRead = 0; // already sent too much! - else { - uMaxPossible -= m_uInstantSentBytes; - if(toRead > uMaxPossible)toRead = uMaxPossible; - } - // limit to packet size - if(toRead > m_pOpt->iPacketSize)toRead = m_pOpt->iPacketSize; - - int written = 0; - if(toRead > 0) - { - // read data - int readed = pFile->read(buffer,toRead); - if(readed < toRead) - { - postErrorEvent(KviError::FileIOError); - break; - } - // send it out - -#ifdef COMPILE_SSL_SUPPORT - if(m_pSSL) - { - written = m_pSSL->write(buffer,toRead); - } else { -#endif - written = kvi_socket_send(m_fd,buffer,toRead); -#ifdef COMPILE_SSL_SUPPORT - } -#endif - - if(written < toRead) - { - if(written < 0) - { -#ifdef COMPILE_SSL_SUPPORT - if(m_pSSL) - { - // ops...might be an SSL error - switch(m_pSSL->getProtocolError(written)) - { - case KviSSL::WantWrite: - case KviSSL::WantRead: - // Async continue... - goto handle_system_error; - break; - case KviSSL::SyscallError: - if(written == 0) - { - raiseSSLError(); - postErrorEvent(KviError::RemoteEndClosedConnection); - goto exit_dcc; - } else { - int iSSLErr = m_pSSL->getLastError(true); - if(iSSLErr != 0) - { - raiseSSLError(); - postErrorEvent(KviError::SSLError); - goto exit_dcc; - } else { - goto handle_system_error; - } - } - break; - case KviSSL::SSLError: - raiseSSLError(); - postErrorEvent(KviError::SSLError); - goto exit_dcc; - break; - default: - postErrorEvent(KviError::SSLError); - goto exit_dcc; - break; - } - } -#endif - - // error ? - if(!handleInvalidSocketRead(written))break; - -handle_system_error: - int err = kvi_socket_error(); -#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - if((err != EAGAIN) || (err != EINTR) || (err != WSAEWOULDBLOCK)) -#else - if((err != EAGAIN)||(err != EINTR)) -#endif - { - postErrorEvent(KviError::translateSystemError(err)); - goto exit_dcc; - } - - } else { - // seek back to the right position - pFile->seek(pFile->pos() - (toRead - written)); - } - } - } else { - // just nothing to send out in this interval - // sleep a while - if(m_uInstantSpeedInterval < (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS - 100)) - { - msleep(100); - } else if(m_uInstantSpeedInterval < (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS - 20)) - { - msleep(20); - } - } - - m_uTotalSentBytes += written; - m_uInstantSentBytes += written; - m_uFilePosition = pFile->pos(); - updateStats(); - } - } else { - if(m_pOpt->bNoAcks && !m_pOpt->bIsTdcc) - { - // at end of the file in a blind dcc send... - // not in a tdcc: we can close the file... - updateStats(); - KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS); - postEvent(parent(),e); - break; - } else { - // upload finished but we're waiting for the last ack - // sleep a bit: don't lag the kernie too much while waiting - msleep(100); - } - } - } - } else { - // after 2 failed selects start to sleep - if(iFailedSelects > 3) - { - // sleep up to 200 msecs - if(iFailedSelects < 100)iFailedSelects++; - msleep(3 * iFailedSelects); - } else { - iFailedSelects++; - } - } - - // include the artificial delay if needed - if(m_pOpt->iIdleStepLengthInMSec > 0) - { - msleep(m_pOpt->iIdleStepLengthInMSec); - } - } - -exit_dcc: - KviMemory::free(buffer); - pFile->close(); - delete pFile; - pFile = 0; - -#ifdef COMPILE_SSL_SUPPORT - if(m_pSSL) - { - KviSSLMaster::freeSSL(m_pSSL); - m_pSSL = 0; - } -#endif - kvi_socket_close(m_fd); - m_fd = KVI_INVALID_SOCKET; -} - -void KviDccSendThread::initGetInfo() -{ - m_pMutex->lock(); -} - -void KviDccSendThread::doneGetInfo() -{ - m_pMutex->unlock(); -} - - -KviDccFileTransfer::KviDccFileTransfer(KviDccDescriptor * dcc) -: KviFileTransfer() -{ - init(); // ensure we're initialized - g_pDccFileTransfers->append(this); - - m_pResumeTimer = 0; - m_pBandwidthDialog = 0; - - KviQString::sprintf(m_szTransferIdString,__tr2qs_ctx("TRANSFER %d","dcc"),id()); - - m_pDescriptor = dcc; - m_pDescriptor->setTransfer(this); - - m_pMarshal = new KviDccMarshal(this); - - connect(m_pMarshal,SIGNAL(error(int)),this,SLOT(handleMarshalError(int))); - connect(m_pMarshal,SIGNAL(connected()),this,SLOT(connected())); - connect(m_pMarshal,SIGNAL(inProgress()),this,SLOT(connectionInProgress())); -#ifdef COMPILE_SSL_SUPPORT - connect(m_pMarshal,SIGNAL(startingSSLHandshake()),this,SLOT(startingSSLHandshake())); - connect(m_pMarshal,SIGNAL(sslError(const char *)),this,SLOT(sslError(const char *))); -#endif - - m_szDccType = dcc->bRecvFile ? "RECV" : "SEND"; - if(dcc->bIsTdcc) m_szDccType.prepend("T"); -#ifdef COMPILE_SSL_SUPPORT - if(dcc->bIsSSL) m_szDccType.prepend("S"); -#endif - m_pSlaveRecvThread = 0; - m_pSlaveSendThread = 0; - - m_tTransferStartTime = 0; - m_tTransferEndTime = 0; - - m_szStatusString = __tr2qs_ctx("Setting up the connection","dcc"); - m_eGeneralStatus = Connecting; - - bool bOk; - m_uTotalFileSize = dcc->bRecvFile ? dcc->szFileSize.toULongLong(&bOk) : dcc->szLocalFileSize.toULongLong(&bOk); - if(!bOk)m_uTotalFileSize = 0; - - if(m_pDescriptor->bRecvFile) - m_uMaxBandwidth = KVI_OPTION_BOOL(KviOption_boolLimitDccRecvSpeed) ? KVI_OPTION_UINT(KviOption_uintMaxDccRecvSpeed) : MAX_DCC_BANDWIDTH_LIMIT; - else - m_uMaxBandwidth = KVI_OPTION_BOOL(KviOption_boolLimitDccSendSpeed) ? KVI_OPTION_UINT(KviOption_uintMaxDccSendSpeed) : MAX_DCC_BANDWIDTH_LIMIT; - - startConnection(); -} - -KviDccFileTransfer::~KviDccFileTransfer() -{ - g_pDccFileTransfers->removeRef(this); - - if(m_pResumeTimer)delete m_pResumeTimer; - if(m_pBandwidthDialog)delete m_pBandwidthDialog; - - if(m_pSlaveRecvThread) - { - m_pSlaveRecvThread->terminate(); - delete m_pSlaveRecvThread; - m_pSlaveRecvThread = 0; - } - - if(m_pSlaveSendThread) - { - m_pSlaveSendThread->terminate(); - delete m_pSlaveSendThread; - m_pSlaveSendThread = 0; - } - - KviThreadManager::killPendingEvents(this); - - delete m_pDescriptor; - delete m_pMarshal; -} - -void KviDccFileTransfer::bandwidthDialogDestroyed() -{ - m_pBandwidthDialog = 0; -} - -KviWindow * KviDccFileTransfer::eventWindow() -{ - KviWindow *w = transferWindow(); - if(w)return w; - return m_pDescriptor->console(); -} - -void KviDccFileTransfer::startConnection() -{ - if(!(m_pDescriptor->bActive)) - { - // PASSIVE CONNECTION - m_szStatusString = __tr2qs_ctx("Attempting a passive DCC %1 connection","dcc").arg(m_szDccType.ptr()); - outputAndLog(m_szStatusString); - } else { - // ACTIVE CONNECTION - m_szStatusString = __tr2qs_ctx("Attempting an active DCC %1 connection","dcc").arg(m_szDccType.ptr()); - outputAndLog(m_szStatusString); - } - - - if(m_pDescriptor->bResume && m_pDescriptor->bRecvFile) - { - QString fName; - KviIrcServerParser::encodeCtcpParameter(m_pDescriptor->szFileName.toUtf8().data(),fName); - if(m_pDescriptor->isZeroPortRequest()) - { - m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC RESUME %s %s %s %s%c", - m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(), - 0x01, - m_pDescriptor->console()->connection()->encodeText(fName).data(), - m_pDescriptor->szPort.toUtf8().data(), - m_pDescriptor->szLocalFileSize.toUtf8().data(), - m_pDescriptor->zeroPortRequestTag(),0x01); - } else { - m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC RESUME %s %s %s%c", - m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(), - 0x01, - m_pDescriptor->console()->connection()->encodeText(fName).data(), - m_pDescriptor->szPort.toUtf8().data(), - m_pDescriptor->szLocalFileSize.toUtf8().data(),0x01); - } - m_szStatusString = __tr2qs_ctx("Sent DCC RESUME request to %1, waiting for ACCEPT","dcc").arg(m_pDescriptor->szNick); - outputAndLog(m_szStatusString); - - // setup the resume timer: we don't want to wait forever - - if(KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) < 5) - KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) = 5; - - if(m_pResumeTimer)delete m_pResumeTimer; - m_pResumeTimer = new QTimer(this); - connect(m_pResumeTimer,SIGNAL(timeout()),this,SLOT(resumeTimedOut())); - m_pResumeTimer->setInterval(KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) * 1000); - m_pResumeTimer->setSingleShot(true); - m_pResumeTimer->start(); - } else { - listenOrConnect(); - } - - displayUpdate(); -} - -void KviDccFileTransfer::listenOrConnect() -{ - if(!(m_pDescriptor->bActive)) - { -#ifdef COMPILE_SSL_SUPPORT - KviError::Code eError = m_pMarshal->dccListen(m_pDescriptor->szListenIp,m_pDescriptor->szListenPort,m_pDescriptor->bDoTimeout,m_pDescriptor->bIsSSL); -#else - KviError::Code eError = m_pMarshal->dccListen(m_pDescriptor->szListenIp,m_pDescriptor->szListenPort,m_pDescriptor->bDoTimeout); -#endif - if(eError != KviError::Success) - handleMarshalError(eError); - } else { -#ifdef COMPILE_SSL_SUPPORT - KviError::Code eError = m_pMarshal->dccConnect(m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data(),m_pDescriptor->bDoTimeout,m_pDescriptor->bIsSSL); -#else - KviError::Code eError = m_pMarshal->dccConnect(m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data(),m_pDescriptor->bDoTimeout); -#endif - if(eError != KviError::Success) - handleMarshalError(eError); - } - - displayUpdate(); -} - -void KviDccFileTransfer::resumeTimedOut() -{ - if(m_pResumeTimer) - { - delete m_pResumeTimer; - m_pResumeTimer = 0; - } - handleMarshalError(KviError::ConnectionTimedOut); -} - -KviWindow * KviDccFileTransfer::dccMarshalOutputWindow() -{ - return transferWindow(); -} - -const char * KviDccFileTransfer::dccMarshalOutputContextString() -{ - return m_szTransferIdString.toUtf8().data(); -} - -QString KviDccFileTransfer::localFileName() -{ - return m_pDescriptor->szLocalFileName; -} - -void KviDccFileTransfer::abort() -{ - if(m_pSlaveRecvThread)m_pSlaveRecvThread->terminate(); - if(m_pSlaveSendThread)m_pSlaveSendThread->terminate(); - if(m_pMarshal)m_pMarshal->abort(); - - if(m_pDescriptor->bRecvFile) - g_pApp->fileDownloadTerminated(false,m_pDescriptor->szFileName.toUtf8().data(),m_pDescriptor->szLocalFileName.toUtf8().data(),m_pDescriptor->szNick.toUtf8().data(),__tr_ctx("Aborted","dcc")); - - QString tmp; - - if(m_pSlaveRecvThread)tmp.setNum(m_pSlaveRecvThread->receivedBytes()); - else if(m_pSlaveSendThread)tmp.setNum(m_pSlaveSendThread->sentBytes()); - else tmp = '0'; - - m_eGeneralStatus = Failure; - m_tTransferEndTime = kvi_unixTime(); - m_szStatusString = __tr2qs_ctx("Transfer failed: ","dcc"); - m_szStatusString += __tr2qs_ctx("Aborted","dcc"); - - KVS_TRIGGER_EVENT_3(KviEvent_OnDCCFileTransferFailed,eventWindow(),QString("Aborted by user"),tmp,m_pDescriptor->idString()); - - outputAndLog(KVI_OUT_DCCERROR,m_szStatusString); - displayUpdate(); -} - -void KviDccFileTransfer::fillContextPopup(KviTalPopupMenu * m) -{ - m->insertItem(__tr2qs_ctx("Configure Bandwidth...","dcc"),this,SLOT(configureBandwidth())); - m->insertSeparator(); - m->insertItem(__tr2qs_ctx("Resend DCC","dcc"),this,SLOT(retryDCC())); - m->insertItem(__tr2qs_ctx("Resend TDCC","dcc"),this,SLOT(retryTDCC())); - m->insertItem(__tr2qs_ctx("Resend RevDCC","dcc"),this,SLOT(retryRevDCC())); - int id = m->insertItem(__tr2qs_ctx("Abort","dcc"),this,SLOT(abort())); - if(!active())m->setItemEnabled(id,false); -} - -void KviDccFileTransfer::configureBandwidth() -{ - if(m_pBandwidthDialog)return; - m_pBandwidthDialog = new KviDccFileTransferBandwidthDialog(g_pFrame,this); - connect(m_pBandwidthDialog,SIGNAL(destroyed()),this,SLOT(bandwidthDialogDestroyed())); - m_pBandwidthDialog->setModal(true); - m_pBandwidthDialog->show(); -} - -void KviDccFileTransfer::retryDCC() -{ - abort(); - QString szRemoteNick = m_pDescriptor->remoteNick(); - QString szFileName = m_pDescriptor->localFileName(); - QString szId = m_pDescriptor->idString(); - KviQString::escapeKvs(&szRemoteNick, KviQString::EscapeSpace); - KviQString::escapeKvs(&szFileName, KviQString::EscapeSpace); - - QString szCommand = "dcc.send -r=$console($dcc.irccontext(" + szId + ")) " + szRemoteNick + " " + szFileName; - KviKvsScript::run(szCommand,g_pActiveWindow); -} - -void KviDccFileTransfer::retryTDCC() -{ - abort(); - QString szRemoteNick = m_pDescriptor->remoteNick(); - QString szFileName = m_pDescriptor->localFileName(); - QString szId = m_pDescriptor->idString(); - KviQString::escapeKvs(&szRemoteNick, KviQString::EscapeSpace); - KviQString::escapeKvs(&szFileName, KviQString::EscapeSpace); - - QString szCommand = "dcc.send -r=$console($dcc.irccontext(" + szId + ")) -t " + szRemoteNick + " " + szFileName; - KviKvsScript::run(szCommand,g_pActiveWindow); -} - -void KviDccFileTransfer::retryRevDCC() -{ - abort(); - QString szRemoteNick = m_pDescriptor->remoteNick(); - QString szFileName = m_pDescriptor->localFileName(); - QString szId = m_pDescriptor->idString(); - KviQString::escapeKvs(&szRemoteNick, KviQString::EscapeSpace); - KviQString::escapeKvs(&szFileName, KviQString::EscapeSpace); - - QString szCommand = "dcc.rsend -z -r=$console($dcc.irccontext(" + szId + ")) " + szRemoteNick + " " + szFileName; - KviKvsScript::run(szCommand,g_pActiveWindow); -} - -void KviDccFileTransfer::fillStatusString(QString &szBuffer) -{ - switch(m_eGeneralStatus) - { - case Connecting: - szBuffer = "connecting"; - break; - case Transferring: - szBuffer = "transferring"; - break; - case Failure: - szBuffer = "failure"; - break; - case Success: - szBuffer = "success"; - break; - default: - szBuffer = "unknown"; - break; - } -} - -bool KviDccFileTransfer::active() -{ - return ((m_eGeneralStatus == Connecting) || (m_eGeneralStatus == Transferring)); -} - -int KviDccFileTransfer::bandwidthLimit() -{ - int iLimit = m_uMaxBandwidth; // we have the cached value anyway... - if(m_pDescriptor->bRecvFile) - { - if(m_pSlaveRecvThread) - { - m_pSlaveRecvThread->initGetInfo(); - iLimit = (int)m_pSlaveRecvThread->bandwidthLimit(); - m_pSlaveRecvThread->doneGetInfo(); - if(iLimit < 0)iLimit = MAX_DCC_BANDWIDTH_LIMIT; - } - } else { - if(m_pSlaveSendThread) - { - m_pSlaveSendThread->initGetInfo(); - iLimit = (int)m_pSlaveSendThread->bandwidthLimit(); - m_pSlaveSendThread->doneGetInfo(); - if(iLimit < 0)iLimit = MAX_DCC_BANDWIDTH_LIMIT; - } - } - return iLimit; -} - -void KviDccFileTransfer::setBandwidthLimit(int iVal) -{ - if(iVal < 0)iVal = MAX_DCC_BANDWIDTH_LIMIT; - if(iVal > MAX_DCC_BANDWIDTH_LIMIT)iVal = MAX_DCC_BANDWIDTH_LIMIT; - m_uMaxBandwidth = iVal; - if(m_pDescriptor->bRecvFile) - { - if(m_pSlaveRecvThread) - { - m_pSlaveRecvThread->initGetInfo(); - m_pSlaveRecvThread->setBandwidthLimit(iVal); - m_pSlaveRecvThread->doneGetInfo(); - } - } else { - if(m_pSlaveSendThread) - { - m_pSlaveSendThread->initGetInfo(); - m_pSlaveSendThread->setBandwidthLimit(iVal); - m_pSlaveSendThread->doneGetInfo(); - } - } -} - -unsigned int KviDccFileTransfer::averageSpeed() -{ - unsigned int uAvgBandwidth = 0; - if(m_pDescriptor->bRecvFile) - { - if(m_pSlaveRecvThread) - { - m_pSlaveRecvThread->initGetInfo(); - uAvgBandwidth = m_pSlaveRecvThread->averageSpeed(); - m_pSlaveRecvThread->doneGetInfo(); - } - } else { - if(m_pSlaveSendThread) - { - m_pSlaveSendThread->initGetInfo(); - uAvgBandwidth = m_pSlaveSendThread->averageSpeed(); - m_pSlaveSendThread->doneGetInfo(); - } - } - return uAvgBandwidth; -} - -unsigned int KviDccFileTransfer::transferredBytes() -{ - unsigned int uTransferred = 0; - if(m_pDescriptor->bRecvFile) - { - if(m_pSlaveRecvThread) - { - m_pSlaveRecvThread->initGetInfo(); - uTransferred = m_pSlaveRecvThread->filePosition(); - m_pSlaveRecvThread->doneGetInfo(); - } - } else { - if(m_pSlaveSendThread) - { - m_pSlaveSendThread->initGetInfo(); - uTransferred = m_pSlaveSendThread->filePosition(); - m_pSlaveSendThread->doneGetInfo(); - } - } - return uTransferred; -} - -void KviDccFileTransfer::displayPaint(QPainter * p,int column, QRect rect) -{ - int width = rect.width(), height = rect.height(); - QString txt; - bool bIsTerminated = ((m_eGeneralStatus == Success) || (m_eGeneralStatus == Failure)); - - switch(column) - { - case COLUMN_TRANSFERTYPE: - { - if(!g_pDccFileTransferIcon)break; - int xoffset = 0; - int yoffset = 0; - if(m_pDescriptor->bRecvFile)yoffset = 64; - switch(m_eGeneralStatus) - { - case Connecting: xoffset = 0; break; - case Transferring: xoffset = 48; break; - case Success: xoffset = 96; break; - case Failure: xoffset = 144; break; - } - p->drawPixmap(rect.left() + 3,rect.top() + 3,*g_pDccFileTransferIcon,xoffset,yoffset,48,64); - } - break; - case COLUMN_FILEINFO: - { - - QFontMetrics fm(p->font()); - - QString szFrom = __tr2qs_ctx("From: ","dcc"); - QString szTo = __tr2qs_ctx("To: ","dcc"); - - int daW1 = fm.width(szFrom); - int daW2 = fm.width(szTo); - if(daW1 < daW2)daW1 = daW2; - int iLineSpacing = fm.lineSpacing(); - - int iY = rect.top() + 4; - - p->setPen(Qt::black); - - KviCString szRemote(KviCString::Format,"dcc://%s@%s:%s/%s",m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data(), - m_pDescriptor->szFileName.toUtf8().data()); - - p->drawText(rect.left() + 4 + daW1,iY,width - (8 + daW1),height - 8,Qt::AlignTop | Qt::AlignLeft, - m_pDescriptor->bRecvFile ? szRemote.ptr() : m_pDescriptor->szLocalFileName.toUtf8().data()); - iY += iLineSpacing; - - p->drawText(rect.left() + 4 + daW1,iY,width - (8 + daW1),height - 8,Qt::AlignTop | Qt::AlignLeft, - m_pDescriptor->bRecvFile ? m_pDescriptor->szLocalFileName.toUtf8().data() : szRemote.ptr()); - iY += iLineSpacing; - - - p->setPen(Qt::darkGray); - - p->drawText(rect.left() + 4, rect.top() + 4,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,szFrom); - p->drawText(rect.left() + 4, rect.top() + 4 + iLineSpacing,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,szTo); - - - p->setPen(QColor(180,180,200)); - - iLineSpacing += 2; - - p->drawRect(rect.left() + 4, rect.top() + height - (iLineSpacing + 4),width - 8,iLineSpacing); - p->fillRect(rect.left() + 5, rect.top() + height - (iLineSpacing + 3),width - 10,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240)); - - p->setPen(Qt::black); - - p->drawText(rect.left() + 7, rect.top() + height - (iLineSpacing + 4),width - 14,iLineSpacing,Qt::AlignVCenter | Qt::AlignLeft,m_szStatusString); - - } - break; - case COLUMN_PROGRESS: - { - - QFontMetrics fm(p->font()); - - int iW = width - 8; - uint uAvgBandwidth = 0; - uint uInstantSpeed = 0; - quint64 uAckedBytes = 0; - quint64 uTransferred = 0; - int iEta = -1; - - if(m_pDescriptor->bRecvFile) - { - if(m_pSlaveRecvThread) - { - m_pSlaveRecvThread->initGetInfo(); - uAvgBandwidth = m_pSlaveRecvThread->averageSpeed(); - uInstantSpeed = m_pSlaveRecvThread->instantSpeed(); - uTransferred = m_pSlaveRecvThread->filePosition(); - m_pSlaveRecvThread->doneGetInfo(); - } - } else { - if(m_pSlaveSendThread) - { - m_pSlaveSendThread->initGetInfo(); - uAvgBandwidth = m_pSlaveSendThread->averageSpeed(); - uInstantSpeed = m_pSlaveSendThread->instantSpeed(); - uTransferred = m_pSlaveSendThread->filePosition(); - uAckedBytes = m_pSlaveSendThread->ackedBytes(); - m_pSlaveSendThread->doneGetInfo(); - } - } - - p->setPen(bIsTerminated ? Qt::lightGray : QColor(210,210,240)); - p->drawRect(rect.left() + 4, rect.top() + 4,iW,12); - - iW -= 2; - - if(m_uTotalFileSize > 0) - { - if(uAvgBandwidth > 0) - { - quint64 uRemaining = m_uTotalFileSize - uTransferred; - iEta = uRemaining / uAvgBandwidth; - } - - if(!m_pDescriptor->bNoAcks && (uAckedBytes > 0) && (uAckedBytes < uTransferred)) - { - // we are sending a file and are getting acks - - double dPerc1 = (double)(((double)uTransferred) * 100.0) / (double)m_uTotalFileSize; - int iL1 = (int) ((((double)iW) * dPerc1) / 100.0); - double dPerc2 = (double)(((double)uAckedBytes) * 100.0) / (double)m_uTotalFileSize; - int iL2 = (int) ((((double)iW) * dPerc2) / 100.0); - int iW2 = iL1 - iL2; - if(iW2 > 0)p->fillRect(rect.left() + 5 + iL2,rect.top() + 5,iW2,10,bIsTerminated ? QColor(150,130,110) : QColor(220,170,100)); - p->fillRect(rect.left() + 5,rect.top() + 5,iL2,10,bIsTerminated ? QColor(140,110,110) : QColor(200,100,100)); - - txt = QString(__tr2qs_ctx("%1 of %2 (%3%)","dcc")).arg(KviQString::makeSizeReadable(uAckedBytes), KviQString::makeSizeReadable(m_uTotalFileSize)).arg(dPerc2,0,'f',2); - } else { - // we are receiving a file or not sending acks - double dPerc = (double)(((double)uTransferred) * 100.0) / (double)m_uTotalFileSize; - int iL = (int) ((((double)iW) * dPerc) / 100.0); - p->fillRect(rect.left() + 5,rect.top() + 5,iL,10,bIsTerminated ? QColor(140,110,110) : QColor(200,100,100)); - - txt = QString(__tr2qs_ctx("%1 of %2 (%3%)","dcc")).arg(KviQString::makeSizeReadable(uTransferred), KviQString::makeSizeReadable(m_uTotalFileSize)).arg(dPerc,0,'f',2); - } - - } else { - txt = QString(__tr2qs_ctx("%1","dcc")).arg(KviQString::makeSizeReadable(uTransferred)); - } - - p->setPen(Qt::black); - - p->drawText(rect.left() + 4,rect.top() + 19,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,txt); - - int iLeftHalf = (iW - 2) / 2; - int iRightHalf = iW - (iLeftHalf + 1); - int iLineSpacing = fm.lineSpacing() + 2; - - if(!bIsTerminated) - { - txt = __tr2qs_ctx("Spd:","dcc"); - txt += " "; - - QString tmpisp; - KviNetUtils::formatNetworkBandwidthString(tmpisp,uInstantSpeed); - txt += tmpisp; - txt += " ["; - } else { - txt = ""; - } - - txt += __tr2qs_ctx("Avg:","dcc"); - txt += " "; - QString tmpspd; - KviNetUtils::formatNetworkBandwidthString(tmpspd,uAvgBandwidth); - txt += tmpspd; - - if(!bIsTerminated) - { - txt += "]"; - } - - int iDaH = height - (iLineSpacing + 4); - - p->setPen(QColor(180,180,200)); - p->drawRect(rect.left() + 4,rect.top() + iDaH,iLeftHalf,iLineSpacing); - p->fillRect(rect.left() + 5,rect.top() + iDaH + 1,iLeftHalf - 2,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240)); - p->setPen(bIsTerminated ? Qt::darkGray : Qt::black); - p->drawText(rect.left() + 6,rect.top() + iDaH,iLeftHalf - 4,iLineSpacing,Qt::AlignLeft | Qt::AlignVCenter,txt); - - if(bIsTerminated) - { - if((m_tTransferStartTime != 0) && (m_tTransferEndTime != 0)) - { - QString tot = KviTimeUtils::formatTimeInterval(kvi_timeSpan(m_tTransferEndTime,m_tTransferStartTime),KviTimeUtils::NoLeadingEmptyIntervals | KviTimeUtils::NoLeadingZeroes); - txt = "TOT: "; - txt += tot; - } else { - txt = ""; - } - } else { - if(iEta >= 0) - { - QString eta = KviTimeUtils::formatTimeInterval(iEta,KviTimeUtils::NoLeadingEmptyIntervals | KviTimeUtils::NoLeadingZeroes); - txt = "ETA: "; - txt += eta; - } else { - txt = "ETA: ?"; - } - } - - p->setPen(QColor(180,180,200)); - p->drawRect(rect.left() + width - (4 + iRightHalf),rect.top() + iDaH,iRightHalf,iLineSpacing); - p->fillRect(rect.left() + width - (3 + iRightHalf),rect.top() + iDaH + 1,iRightHalf - 2,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240)); - p->setPen(bIsTerminated ? Qt::darkGray : Qt::black); - p->drawText(rect.left() + width - (2 + iRightHalf),rect.top() + iDaH,iRightHalf - 4,iLineSpacing,Qt::AlignLeft | Qt::AlignVCenter,txt); - - } - break; - } - -} - -int KviDccFileTransfer::displayHeight(int iLineSpacing) -{ - int iH = (iLineSpacing * 3) + 10; - return iH >= 70 ? iH : 70; -} - -QString KviDccFileTransfer::tipText() -{ - QString s; - - s = QString("
").arg(m_szDccType.ptr()).arg(id()); - - s += ""; - s += ""; - s += "
DCC %1 (ID %2)
"; - s += __tr2qs_ctx("Transfer Log","dcc"); - s += "
"; - s += m_szTransferLog; - s += "
"; - - return s; -} - -void KviDccFileTransfer::init() -{ - if(g_pDccFileTransfers)return; - g_pDccFileTransfers = new KviPointerList; - g_pDccFileTransfers->setAutoDelete(false); - - QPixmap * pix = g_pIconManager->getImage("kvi_dccfiletransfericons.png", false); - if(pix)g_pDccFileTransferIcon = new QPixmap(*pix); - else g_pDccFileTransferIcon = 0; -} - -void KviDccFileTransfer::done() -{ - if(!g_pDccFileTransfers)return; - while(KviDccFileTransfer * t = g_pDccFileTransfers->first()) - delete t; - delete g_pDccFileTransfers; - g_pDccFileTransfers = 0; - if(g_pDccFileTransferIcon)delete g_pDccFileTransferIcon; - g_pDccFileTransferIcon = 0; -} - -unsigned int KviDccFileTransfer::transferCount() -{ - if(!g_pDccFileTransfers)return 0; - return g_pDccFileTransfers->count(); -} - -KviDccFileTransfer * KviDccFileTransfer::nonFailedTransferWithLocalFileName(const QString &szLocalFileName) -{ - if(!g_pDccFileTransfers)return 0; - for(KviDccFileTransfer * t = g_pDccFileTransfers->first();t;t = g_pDccFileTransfers->next()) - { -#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - // on windows the file names are case insensitive - if(t->localFileName().toLower() == szLocalFileName.toLower()) -#else - if(t->localFileName() == szLocalFileName) -#endif - { - if(t->m_eGeneralStatus != Failure) - return t; - } - } - return 0; -} - -unsigned int KviDccFileTransfer::runningTransfersCount() -{ - if(!g_pDccFileTransfers)return 0; - unsigned int cnt = 0; - for(KviDccFileTransfer * t = g_pDccFileTransfers->first();t;t = g_pDccFileTransfers->next()) - { - if(t->active())cnt++; - } - return cnt; -} - -bool KviDccFileTransfer::handleResumeAccepted(const char * filename,const char * port,const char * szZeroPortTag) -{ - if(!g_pDccFileTransfers)return false; - - for(KviDccFileTransfer * t = g_pDccFileTransfers->first();t;t = g_pDccFileTransfers->next()) - { - if(t->resumeAccepted(filename,port,szZeroPortTag))return true; - } - - return false; -} - -bool KviDccFileTransfer::handleResumeRequest(const char * filename,const char * port,quint64 filePos) -{ - if(!g_pDccFileTransfers) - return false; - - for(KviDccFileTransfer * t = g_pDccFileTransfers->first();t;t = g_pDccFileTransfers->next()) - { - if(t->doResume(filename,port,filePos)) - return true; - } - - return false; -} - -void KviDccFileTransfer::outputAndLog(const QString &s) -{ - KviWindow * out = transferWindow(); - addToTransferLog(s); - if(out)out->output(KVI_OUT_DCCMSG,"[%Q]: %Q",&m_szTransferIdString,&s); -} - -void KviDccFileTransfer::outputAndLog(int msgtype,const QString &s) -{ - KviWindow * out = transferWindow(); - addToTransferLog(s); - if(out)out->output(msgtype,"[%Q]: %Q",&m_szTransferIdString,&s); -} - - -void KviDccFileTransfer::addToTransferLog(const QString &s) -{ - QDateTime dt = QDateTime::currentDateTime(); - QString ts; - ts.sprintf("[%4d.%2d.%2d %2d:%2d:%2d] ",dt.date().year(),dt.date().month(),dt.date().day(),dt.time().hour(),dt.time().minute(),dt.time().second()); - m_szTransferLog += ts+s; - m_szTransferLog += "
"; -} - -void KviDccFileTransfer::connectionInProgress() -{ - if(m_pDescriptor->bActive) - { - // ACTIVE CONNECTION -// if((kvi_strEqualCS(m_szDccType.ptr(), "RECV")) || (kvi_strEqualCS(m_szDccType.ptr(),"TRECV"))) -// { -// // FIXME: that's not true!... we're NOT connected here -// if(TRIGGER_EVENT_5PARAM_RETVALUE(KviEvent_OnDCCGetConnected,this,m_pDescriptor->szPort.ptr(),m_pDescriptor->szFileName.ptr(),m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(),m_pDescriptor->szHost.ptr())); -// } else { -// if(TRIGGER_EVENT_5PARAM_RETVALUE(KviEvent_OnDCCSendConnected,this,m_pDescriptor->szPort.ptr(),m_pDescriptor->szFileName.ptr(),m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(),m_pDescriptor->szHost.ptr())); -// } -// - m_szStatusString = __tr2qs_ctx("Contacting host %1 on port %2","dcc").arg(m_pDescriptor->szIp, m_pDescriptor->szPort); - outputAndLog(m_szStatusString); - displayUpdate(); - return; - } - - // PASSIVE CONNECTION - m_szStatusString = __tr2qs_ctx("Listening on interface %1 port %2","dcc").arg(m_pMarshal->localIp(), m_pMarshal->localPort()); - outputAndLog(m_szStatusString); - - if(m_pDescriptor->bSendRequest) - { - QString ip; - if(!m_pDescriptor->szFakeIp.isEmpty()) - { - ip = m_pDescriptor->szFakeIp; - } else { - ip = m_pDescriptor->szListenIp; - - if(KVI_OPTION_BOOL(KviOption_boolDccGuessIpFromServerWhenLocalIsUnroutable)) - { - if(!KviNetUtils::isRoutableIpString(ip)) - { - // try to get the IP that the IRC server can see - if(m_pDescriptor->console()) - { - QString tmp = m_pDescriptor->console()->connection() ? m_pDescriptor->console()->connection()->userInfo()->hostIp() : ""; - if(!tmp.isEmpty()) - { - ip = tmp; - outputAndLog(__tr2qs_ctx("The local IP address is private, determining from IRC server: %1","dcc").arg(ip)); - } else { - outputAndLog(__tr2qs_ctx("The local IP address is private, but unable to determine it from the IRC server","dcc")); - } - } else { - outputAndLog(__tr2qs_ctx("The local IP address is private, but have no IRC server to determine it from","dcc")); - } - } - } - } - - KviCString port = !m_pDescriptor->szFakePort.isEmpty() ? m_pDescriptor->szFakePort : m_pMarshal->localPort(); - //#warning "OPTION FOR SENDING 127.0.0.1 and so on (not an unsigned nuumber)" - struct in_addr a; - if(KviNetUtils::stringIpToBinaryIp(ip,&a))ip.setNum(htonl(a.s_addr)); - - QString tmp = m_pDescriptor->szFileName; - // just to be sure - KviQString::cutToLast(tmp,'/'); - KviQString::cutToLast(tmp,'\\'); - - QString fName; - - // BUG-TO-BUG mIrc compatibility - if(KVI_OPTION_BOOL(KviOption_boolDCCFileTransferReplaceOutgoingSpacesWithUnderscores)) - tmp.replace(" ","_"); - - KviIrcServerParser::encodeCtcpParameter(tmp.toUtf8().data(),fName); - // Zero port requests want DCC SEND as back-request - KviCString szReq; - - if(m_pDescriptor->isZeroPortRequest()) - { - szReq = "SEND"; - if(m_pDescriptor->bIsTdcc) szReq.prepend("T"); -#ifdef COMPILE_SSL_SUPPORT - if(m_pDescriptor->bIsSSL) szReq.prepend("S"); -#endif - m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC %s %s %s %s %s %s%c", - m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(), - 0x01, - m_pDescriptor->console()->connection()->encodeText(szReq.ptr()).data(), - m_pDescriptor->console()->connection()->encodeText(fName).data(), - ip.toUtf8().data(),port.ptr(), - m_pDescriptor->szFileSize.toUtf8().data(),m_pDescriptor->zeroPortRequestTag(),0x01); - } else { - szReq = m_szDccType; - m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC %s %s %s %s %Q%c", - m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(), - 0x01, - m_pDescriptor->console()->connection()->encodeText(szReq.ptr()).data(), - m_pDescriptor->console()->connection()->encodeText(fName).data(), - ip.toUtf8().data(),port.ptr(), - &(m_pDescriptor->szLocalFileSize),0x01); - } - outputAndLog(__tr2qs_ctx("Sent DCC %1 request to %2, waiting for remote client to connect...","dcc").arg(szReq.ptr(), m_pDescriptor->szNick)); - } else { - outputAndLog(__tr2qs_ctx("DCC %1 request not sent, awaiting manual connection","dcc").arg(m_szDccType.ptr())); - } - - KVS_TRIGGER_EVENT_1(KviEvent_OnDCCFileTransferConnectionInProgress,eventWindow(),m_pDescriptor->idString()); - - displayUpdate(); -} - -void KviDccFileTransfer::startingSSLHandshake() -{ -#ifdef COMPILE_SSL_SUPPORT - outputAndLog(KVI_OUT_SSL,__tr2qs_ctx("Low-level transport connection established","dcc")); - outputAndLog(KVI_OUT_SSL,__tr2qs_ctx("Starting Secure Socket Layer handshake","dcc")); -#endif -} - -void KviDccFileTransfer::sslError(const char * msg) -{ -#ifdef COMPILE_SSL_SUPPORT - outputAndLog(KVI_OUT_DCCERROR,__tr2qs_ctx("[SSL ERROR]: %1","dcc").arg(msg)); -#endif -} - -bool KviDccFileTransfer::event(QEvent *e) -{ - if(e->type() == KVI_THREAD_EVENT) - { - switch(((KviThreadEvent *)e)->id()) - { - case KVI_DCC_THREAD_EVENT_ERROR: - { - KviError::Code * pError = ((KviThreadDataEvent *)e)->getData(); - QString szErrorString = KviError::getDescription(*pError); - delete pError; - if(m_pDescriptor->bRecvFile) - g_pApp->fileDownloadTerminated(false,m_pDescriptor->szFileName.toUtf8().data(),m_pDescriptor->szLocalFileName.toUtf8().data(),m_pDescriptor->szNick.toUtf8().data(),szErrorString.toUtf8().data()); - - m_szStatusString = __tr2qs_ctx("Transfer failed: ","dcc"); - m_szStatusString += szErrorString; - m_eGeneralStatus = Failure; - m_tTransferEndTime = kvi_unixTime(); - - KVS_TRIGGER_EVENT_3(KviEvent_OnDCCFileTransferFailed, - eventWindow(), - szErrorString, - (kvs_int_t)(m_pSlaveRecvThread ? m_pSlaveRecvThread->receivedBytes() : m_pSlaveSendThread->sentBytes()), - m_pDescriptor->idString()); - - outputAndLog(KVI_OUT_DCCERROR,m_szStatusString); - displayUpdate(); - return true; - } - break; - case KVI_DCC_THREAD_EVENT_SUCCESS: - { - // FIXME: for >= 3.2.0 change this text to - // File Upload/Download terminated, or something like this - if(KVI_OPTION_BOOL(KviOption_boolNotifyDccSendSuccessInConsole)) - { - KviConsoleWindow *c; - if(!g_pApp->windowExists(m_pDescriptor->console())) c=g_pApp->activeConsole(); - else c=m_pDescriptor->console(); - c->output(KVI_OUT_DCCMSG,__tr2qs_ctx("DCC %s transfer with %Q@%Q:%Q completed: \r![!dbl]play $0\r%s\r","dcc"), - m_pDescriptor->bIsTdcc ? (m_pDescriptor->bRecvFile ? "TRECV" : "TSEND") : (m_pDescriptor->bRecvFile ? "RECV" : "SEND"), - &(m_pDescriptor->szNick),&(m_pDescriptor->szIp),&(m_pDescriptor->szPort), - &(m_pDescriptor->szLocalFileName)); - } - /* - // Also add an optional message to the notifier, unless it is an AVATAR download! - if(KVI_OPTION_BOOL(KviOption_boolNotifiDccDownloadSuccessInNotifier)) - { - QString szMsg; - KviQString::sprintf(szMsg,__tr2qs_ctx("")); - g_pApp->notifierMessage(0,KVI_SMALLICON_DCCMSG,szMsg,KVI_OPTION_UINT(KviOption_uintNotifierAutoHideTime)); - } - */ - if(m_pDescriptor->bRecvFile)g_pApp->fileDownloadTerminated(true,m_pDescriptor->szFileName.toUtf8().data(),m_pDescriptor->szLocalFileName.toUtf8().data(),m_pDescriptor->szNick.toUtf8().data()); - m_szStatusString = __tr2qs_ctx("Transfer completed","dcc"); - outputAndLog(m_szStatusString); - m_eGeneralStatus = Success; - m_tTransferEndTime = kvi_unixTime(); - if (m_pResumeTimer) delete m_pResumeTimer; - - KVS_TRIGGER_EVENT_2(KviEvent_OnDCCFileTransferSuccess, - eventWindow(), - (kvs_int_t)(m_pSlaveRecvThread ? m_pSlaveRecvThread->receivedBytes() : m_pSlaveSendThread->sentBytes()), - m_pDescriptor->idString()); - - displayUpdate(); - - if(KVI_OPTION_BOOL(KviOption_boolAutoCloseDccSendOnSuccess))die(); - return true; - } - break; - case KVI_DCC_THREAD_EVENT_MESSAGE: - { - KviCString * str = ((KviThreadDataEvent *)e)->getData(); - outputAndLog(QString(__tr_no_xgettext_ctx(str->ptr(),"dcc"))); - delete str; - return true; - } - break; - default: - qDebug("Invalid event type %d received",((KviThreadEvent *)e)->id()); - break; - } - } -//#warning "Remove this!" -// if(e->type() == QEvent::Close)qDebug("Close event received"); - return KviFileTransfer::event(e); -} - -void KviDccFileTransfer::handleMarshalError(KviError::Code eError) -{ - QString szErr = KviError::getDescription(eError); - m_eGeneralStatus = Failure; - m_szStatusString = __tr2qs_ctx("Transfer failed: ","dcc"); - m_szStatusString += szErr; - outputAndLog(m_szStatusString); - KVS_TRIGGER_EVENT_3(KviEvent_OnDCCFileTransferFailed,eventWindow(),szErr,(kvs_int_t)0,m_pDescriptor->idString()); - displayUpdate(); -} - -void KviDccFileTransfer::connected() -{ - outputAndLog(__tr2qs_ctx("Connected to %1:%2","dcc").arg(m_pMarshal->remoteIp(), m_pMarshal->remotePort())); - outputAndLog(__tr2qs_ctx("Local end is %1:%2","dcc").arg(m_pMarshal->localIp(), m_pMarshal->localPort())); - - m_tTransferStartTime = kvi_unixTime(); - - if(!(m_pDescriptor->bActive)) - { - m_pDescriptor->szIp = m_pMarshal->remoteIp(); - m_pDescriptor->szPort = m_pMarshal->remotePort(); - m_pDescriptor->szHost = m_pMarshal->remoteIp(); - } - - if(m_pDescriptor->bRecvFile) - { - KviDccRecvThreadOptions * o = new KviDccRecvThreadOptions; - o->szFileName = m_pDescriptor->szLocalFileName.toUtf8().data(); - bool bOk; - o->uTotalFileSize = m_pDescriptor->szFileSize.toULongLong(&bOk); - if(!bOk)o->uTotalFileSize = 0; - o->bResume = m_pDescriptor->bResume; - o->iIdleStepLengthInMSec = KVI_OPTION_BOOL(KviOption_boolDccSendForceIdleStep) ? KVI_OPTION_UINT(KviOption_uintDccSendIdleStepInMSec) : 0; - o->bIsTdcc = m_pDescriptor->bIsTdcc; - o->bSendZeroAck = KVI_OPTION_BOOL(KviOption_boolSendZeroAckInDccRecv); - o->bNoAcks = m_pDescriptor->bNoAcks; - o->uMaxBandwidth = m_uMaxBandwidth; - m_pSlaveRecvThread = new KviDccRecvThread(this,m_pMarshal->releaseSocket(),o); - -#ifdef COMPILE_SSL_SUPPORT - KviSSL * s = m_pMarshal->releaseSSL(); - if(s) - { - m_pSlaveRecvThread->setSSL(s); - } -#endif - m_pSlaveRecvThread->start(); - } else { - KviDccSendThreadOptions * o = new KviDccSendThreadOptions; - o->szFileName = m_pDescriptor->szLocalFileName.toUtf8().data(); - o->bFastSend = KVI_OPTION_BOOL(KviOption_boolUseFastDccSend); - o->iIdleStepLengthInMSec = KVI_OPTION_BOOL(KviOption_boolDccSendForceIdleStep) ? KVI_OPTION_UINT(KviOption_uintDccSendIdleStepInMSec) : 0; - bool bOk; - o->bIsTdcc = m_pDescriptor->bIsTdcc; - o->uStartPosition = m_pDescriptor->szFileSize.toULongLong(&bOk); - if(!bOk) o->uStartPosition = 0; - o->iPacketSize = KVI_OPTION_UINT(KviOption_uintDccSendPacketSize); - if(o->iPacketSize < 32)o->iPacketSize = 32; - o->uMaxBandwidth = m_uMaxBandwidth; - o->bNoAcks = m_pDescriptor->bNoAcks; - m_pSlaveSendThread = new KviDccSendThread(this,m_pMarshal->releaseSocket(),o); -#ifdef COMPILE_SSL_SUPPORT - KviSSL * s = m_pMarshal->releaseSSL(); - if(s) - { - m_pSlaveSendThread->setSSL(s); - } -#endif - m_pSlaveSendThread->start(); - } - - m_eGeneralStatus = Transferring; - m_szStatusString = __tr2qs_ctx("Transferring data","dcc"); - - KVS_TRIGGER_EVENT_1(KviEvent_OnDCCFileTransferBegin,eventWindow(),m_pDescriptor->idString()); - - outputAndLog(m_szStatusString); - displayUpdate(); -} - -bool KviDccFileTransfer::resumeAccepted(const char *filename,const char *port,const char *szZeroPortTag) -{ - if(!(kvi_strEqualCI(filename,m_pDescriptor->szFileName.toUtf8().data()) || KVI_OPTION_BOOL(KviOption_boolAcceptBrokenFileNameDccResumeRequests))) - return false; - - if(!(kvi_strEqualCI(port,m_pDescriptor->szPort.toUtf8().data()) && - (!m_pSlaveRecvThread) && m_pDescriptor->bResume && m_pDescriptor->bRecvFile && m_pResumeTimer)) - return false; - - if(kvi_strEqualCI(port,"0")) - { - if(!kvi_strEqualCI(szZeroPortTag,m_pDescriptor->zeroPortRequestTag())) - return false; - } - - delete m_pResumeTimer; - m_pResumeTimer = 0; - - outputAndLog(__tr2qs_ctx("RESUME accepted, transfer will begin at position %1","dcc").arg(m_pDescriptor->szLocalFileSize)); - - listenOrConnect(); - - /* - int ret = m_pMarshal->dccConnect(m_pDescriptor->szIp.toUtf8().data(), - m_pDescriptor->szPort.toUtf8().data(),m_pDescriptor->bDoTimeout); - - if(ret != KviError::Success)handleMarshalError(ret); - else { - m_szStatusString = __tr2qs_ctx("Contacting host %1 on port %2","dcc").arg(m_pDescriptor->szIp, m_pDescriptor->szPort); - outputAndLog(m_szStatusString); - displayUpdate(); - } - */ - - return true; -} - -bool KviDccFileTransfer::doResume(const char * filename,const char * port,quint64 filePos) -{ - if(m_pSlaveRecvThread) - return false; // we're already receiving stuff... - if(m_pSlaveSendThread) - return false; // we're already sending stuff... - - if(m_pDescriptor->bRecvFile) - return false; // we're receiving... can't resume anything - - bool bFileNameMatches = KviQString::equalCI(filename,m_pDescriptor->szFileName); - bool bPortMatches = KviQString::equalCI(port,m_pMarshal->dccPort()); - - if(!bPortMatches) - { - // port doesn't match - if(!bFileNameMatches) - return false; // neither filename nor port match - - if(!KVI_OPTION_BOOL(KviOption_boolAcceptMismatchedPortDccResumeRequests)) - return false; - - // hmm.. try to accept a mismatched port request - - if(_OUTPUT_VERBOSE) - outputAndLog(KVI_OUT_DCCMSG,__tr2qs_ctx("Processing RESUME request with mismatched port (%1)","dcc").arg(port)); - } - - // port matches - - if(!bFileNameMatches) - { - // bad file name - if(!bPortMatches) - return false; // neither filename nor port match - - // port matches (this is very likely to be the right transfer) - - if(!KVI_OPTION_BOOL(KviOption_boolAcceptBrokenFileNameDccResumeRequests)) - { - if(_OUTPUT_VERBOSE) - outputAndLog( - KVI_OUT_DCCMSG, - __tr2qs_ctx("Invalid RESUME request: Invalid file name (got '%1' but should be '%2')","dcc") - .arg(filename) - .arg(m_pDescriptor->szFileName) - ); - return false; // bad file name - } - - if(_OUTPUT_VERBOSE) - outputAndLog(KVI_OUT_DCCMSG,__tr2qs_ctx("Processing RESUME request with broken filename (%1)","dcc").arg(filename)); - } - - bool bOk; - quint64 iLocalFileSize = m_pDescriptor->szLocalFileSize.toULongLong(&bOk); - - if(!bOk) - { - // ops...internal error - outputAndLog(KVI_OUT_DCCERROR,__tr2qs_ctx("Internal error in RESUME request","dcc")); - return false; - } - - if(iLocalFileSize <= filePos) - { - outputAndLog(KVI_OUT_DCCERROR,__tr2qs_ctx("Invalid RESUME request: Position %1 is larger than file size","dcc").arg(filePos)); - return false; - } - - outputAndLog(KVI_OUT_DCCERROR,__tr2qs_ctx("Accepting RESUME request, transfer will begin at position %1","dcc").arg(filePos)); - - m_pDescriptor->szFileSize.setNum(filePos); - - KviCString szBuffy; - KviIrcServerParser::encodeCtcpParameter(filename,szBuffy); - - m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC ACCEPT %s %s %u%c", - m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(), - 0x01, - m_pDescriptor->console()->connection()->encodeText(szBuffy.ptr()).data(), - port,filePos,0x01 - ); - - return true; -} - -KviDccThread * KviDccFileTransfer::getSlaveThread() -{ - if(m_pDescriptor->bRecvFile) - { - return m_pSlaveRecvThread; - } else { - return m_pSlaveSendThread; - } -} - - -KviDccFileTransferBandwidthDialog::KviDccFileTransferBandwidthDialog(QWidget * pParent,KviDccFileTransfer * t) -: QDialog(pParent) -{ - QGridLayout * g = new QGridLayout(this); - - m_pTransfer = t; - int iVal = m_pTransfer->bandwidthLimit(); - - QString szText = __tr2qs_ctx("Configure bandwidth for DCC transfer %1","dcc").arg(t->id()); - setWindowTitle(szText); - - szText = t->isFileUpload() ? __tr2qs_ctx("Limit upload bandwidth to","dcc") : __tr2qs_ctx("Limit download bandwidth to","dcc"); - - m_pEnableLimitCheck = new QCheckBox(szText,this); - g->addWidget(m_pEnableLimitCheck,0,0); - - m_pEnableLimitCheck->setChecked((iVal >= 0) && (iVal < MAX_DCC_BANDWIDTH_LIMIT)); - - m_pLimitBox = new QSpinBox(this); - m_pLimitBox->setMinimum(0); - m_pLimitBox->setMaximum(MAX_DCC_BANDWIDTH_LIMIT-1); - m_pLimitBox->setSingleStep(1); - - m_pLimitBox->setEnabled((iVal >= 0) && (iVal < MAX_DCC_BANDWIDTH_LIMIT)); - connect(m_pEnableLimitCheck,SIGNAL(toggled(bool)),m_pLimitBox,SLOT(setEnabled(bool))); - g->addWidget(m_pLimitBox,0,1,1,2); - - szText = " "; - szText += __tr2qs_ctx("bytes/sec","dcc"); - m_pLimitBox->setSuffix(szText); - m_pLimitBox->setValue(iVal < MAX_DCC_BANDWIDTH_LIMIT ? iVal : 0); - - QPushButton * pb = new QPushButton(__tr2qs_ctx("OK","dcc"),this); - connect(pb,SIGNAL(clicked()),this,SLOT(okClicked())); - pb->setMinimumWidth(80); - g->addWidget(pb,2,2); - - pb = new QPushButton(__tr2qs_ctx("Cancel","dcc"),this); - connect(pb,SIGNAL(clicked()),this,SLOT(cancelClicked())); - pb->setMinimumWidth(80); - g->addWidget(pb,2,1); - - g->setColumnStretch(0,1); - g->setRowStretch(1,1); -} - -KviDccFileTransferBandwidthDialog::~KviDccFileTransferBandwidthDialog() -{ -} - -void KviDccFileTransferBandwidthDialog::okClicked() -{ - int iVal = MAX_DCC_BANDWIDTH_LIMIT; - if(m_pEnableLimitCheck->isChecked()) - { - iVal = m_pLimitBox->value(); - if(iVal < 0)iVal = MAX_DCC_BANDWIDTH_LIMIT; - if(iVal > MAX_DCC_BANDWIDTH_LIMIT)iVal = MAX_DCC_BANDWIDTH_LIMIT; - } - m_pTransfer->setBandwidthLimit(iVal); - delete this; -} - -void KviDccFileTransferBandwidthDialog::cancelClicked() -{ - delete this; -} - -void KviDccFileTransferBandwidthDialog::closeEvent(QCloseEvent * e) -{ - e->ignore(); - delete this; -} - - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_send.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/dcc/send.h b/src/modules/dcc/send.h deleted file mode 100644 index b4f5eb467..000000000 --- a/src/modules/dcc/send.h +++ /dev/null @@ -1,256 +0,0 @@ -#ifndef _SEND_H_ -#define _SEND_H_ -//============================================================================= -// -// File : send.h -// Creation date : Tue Sep 24 09 2000 15:06:12 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "descriptor.h" -#include "window.h" -#include "thread.h" - -#include "KviWindow.h" -#include "KviCString.h" -#include "kvi_sockettype.h" -#include "KviPointerList.h" -#include "KviFileTransfer.h" -#include "KviTimeUtils.h" -#include "KviTalPopupMenu.h" -#include "KviTalHBox.h" -#include "KviTalVBox.h" - -#include -#include -#include -#include -#include - -class QSpinBox; -class QTimer; -class QPainter; -class KviDccFileTransfer; -class KviDccMarshal; -class KviTalPopupMenu; - -typedef struct _KviDccSendThreadOptions -{ - KviCString szFileName; - quint64 uStartPosition; - int iPacketSize; - int iIdleStepLengthInMSec; - bool bFastSend; - bool bNoAcks; - bool bIsTdcc; - unsigned int uMaxBandwidth; -} KviDccSendThreadOptions; - - -class KviDccSendThread : public KviDccThread -{ -public: - KviDccSendThread(QObject * par,kvi_socket_t fd,KviDccSendThreadOptions * opt); - ~KviDccSendThread(); -private: - // stats: SHARED!!! - uint m_uAverageSpeed; - uint m_uInstantSpeed; - quint64 m_uFilePosition; - quint64 m_uAckedBytes; - quint64 m_uTotalSentBytes; - // internal - unsigned long m_uStartTime; - unsigned long m_uInstantSpeedInterval; - quint64 m_uInstantSentBytes; - KviDccSendThreadOptions * m_pOpt; - KviMSecTimeInterval * m_pTimeInterval; // used for computing the instant bandwidth but not only -public: - void initGetInfo(); - uint averageSpeed(){ return m_uAverageSpeed; }; - uint instantSpeed(){ return m_uInstantSpeed; }; - quint64 filePosition(){ return m_uFilePosition; }; - // sent ONLY in this session - quint64 sentBytes(){ return m_uTotalSentBytes; }; - quint64 ackedBytes(){ return m_uAckedBytes; }; - unsigned int bandwidthLimit(){ return m_pOpt->uMaxBandwidth; }; - void setBandwidthLimit(unsigned int uMaxBandwidth){ m_pOpt->uMaxBandwidth = uMaxBandwidth; }; - void doneGetInfo(); -protected: - void updateStats(); - virtual void run(); -}; - -typedef struct _KviDccRecvThreadOptions -{ - bool bResume; - KviCString szFileName; - quint64 uTotalFileSize; - int iIdleStepLengthInMSec; - bool bSendZeroAck; - bool bNoAcks; - bool bIsTdcc; - unsigned int uMaxBandwidth; -} KviDccRecvThreadOptions; - -class KviDccRecvThread : public KviDccThread -{ -public: - KviDccRecvThread(QObject * par,kvi_socket_t fd,KviDccRecvThreadOptions * opt); - ~KviDccRecvThread(); -protected: - KviDccRecvThreadOptions * m_pOpt; - - // stats: SHARED! - uint m_uAverageSpeed; - uint m_uInstantSpeed; - quint64 m_uFilePosition; - quint64 m_uTotalReceivedBytes; - - // internal - unsigned long m_uStartTime; - KviMSecTimeInterval * m_pTimeInterval; // used for computing the instant bandwidth - quint64 m_uInstantReceivedBytes; - quint64 m_uInstantSpeedInterval; - QFile * m_pFile; -public: - void initGetInfo(); - uint averageSpeed(){ return m_uAverageSpeed; }; - uint instantSpeed(){ return m_uInstantSpeed; }; - quint64 filePosition(){ return m_uFilePosition; }; - // received ONLY in this session - quint64 receivedBytes(){ return m_uTotalReceivedBytes; }; - unsigned int bandwidthLimit(){ return m_pOpt->uMaxBandwidth; }; - void setBandwidthLimit(unsigned int uMaxBandwidth){ m_pOpt->uMaxBandwidth = uMaxBandwidth; }; - void doneGetInfo(); -protected: - void postMessageEvent(const char * msg); - void updateStats(); - bool sendAck(int filePos); - virtual void run(); -}; - - -class KviDccFileTransferBandwidthDialog : public QDialog -{ - Q_OBJECT -public: - KviDccFileTransferBandwidthDialog(QWidget * pParent,KviDccFileTransfer * t); - ~KviDccFileTransferBandwidthDialog(); -protected: - KviDccFileTransfer * m_pTransfer; - QCheckBox * m_pEnableLimitCheck; - QSpinBox * m_pLimitBox; -protected: - virtual void closeEvent(QCloseEvent *e); -protected slots: - void okClicked(); - void cancelClicked(); -}; - - -class KviDccFileTransfer : public KviFileTransfer, public KviDccMarshalOutputContext -{ - enum GeneralStatus { Connecting, Transferring, Success, Failure }; - Q_OBJECT -public: - KviDccFileTransfer(KviDccDescriptor * dcc); - ~KviDccFileTransfer(); -private: - KviDccSendThread * m_pSlaveSendThread; - KviDccRecvThread * m_pSlaveRecvThread; - KviDccDescriptor * m_pDescriptor; - KviDccMarshal * m_pMarshal; - - KviCString m_szTarget; - KviCString m_szDccType; - QString m_szTransferIdString; - - QString m_szStatusString; - GeneralStatus m_eGeneralStatus; - - QString m_szTransferLog; // html - - kvi_time_t m_tTransferStartTime; - kvi_time_t m_tTransferEndTime; - // cached stats - quint64 m_uTotalFileSize; // total file size to transfer - - unsigned int m_uMaxBandwidth; - KviDccFileTransferBandwidthDialog * m_pBandwidthDialog; - - QTimer * m_pResumeTimer; // used to signal resume timeout -public: - bool resumeAccepted(const char * filename,const char * port,const char *szZeroPortTag); - bool doResume(const char * filename,const char * port,quint64 filePos); - - static void init(); - static void done(); - static unsigned int runningTransfersCount(); - static KviDccFileTransfer * nonFailedTransferWithLocalFileName(const QString &szLocalFileName); - static unsigned int transferCount(); - static bool handleResumeAccepted(const char * filename,const char * port,const char * szZeroPortTag); - static bool handleResumeRequest(const char * filename,const char * port,quint64 filePos); - - virtual bool event(QEvent *e); - - virtual KviWindow * dccMarshalOutputWindow(); - virtual const char * dccMarshalOutputContextString(); - - virtual void displayPaint(QPainter * p,int column, QRect rect); - virtual int displayHeight(int iLineSpacing); - virtual void fillContextPopup(KviTalPopupMenu * m); - virtual void fillStatusString(QString &szBuffer); - virtual bool active(); - virtual QString tipText(); - virtual QString localFileName(); - - bool isFileUpload(){ return m_pDescriptor->isFileUpload(); }; - - unsigned int averageSpeed(); - unsigned int transferredBytes(); - - int bandwidthLimit(); - void setBandwidthLimit(int iVal); - virtual KviDccThread * getSlaveThread(); -protected: - void startConnection(); - void listenOrConnect(); - void addToTransferLog(const QString &s); - void outputAndLog(const QString &s); - void outputAndLog(int msgtype,const QString &s); - KviWindow * eventWindow(); -protected slots: - void connectionInProgress(); - void sslError(const char * msg); - void startingSSLHandshake(); - void handleMarshalError(KviError::Code); - void connected(); - void bandwidthDialogDestroyed(); - void configureBandwidth(); - void resumeTimedOut(); -public slots: - void abort(); - void retryDCC(); - void retryTDCC(); - void retryRevDCC(); -}; - -#endif //_SEND_H_ diff --git a/src/modules/dcc/thread.cpp b/src/modules/dcc/thread.cpp deleted file mode 100644 index 9930866df..000000000 --- a/src/modules/dcc/thread.cpp +++ /dev/null @@ -1,114 +0,0 @@ -//============================================================================= -// -// File : thread.cpp -// Creation date : Tue Sep 20 09 2000 18:29:51 CEST Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "thread.h" - -#include "kvi_debug.h" -#include "KviWindow.h" -#include "KviError.h" -#include "KviMemory.h" -#include "KviMemory.h" -#include "KviNetUtils.h" -#include "kvi_socket.h" - -#ifdef COMPILE_SSL_SUPPORT - #include "KviSSLMaster.h" -#endif - -KviDccThread::KviDccThread(QObject * par,kvi_socket_t fd) -: KviSensitiveThread() -{ - m_pParent = par; - m_fd = fd; - m_pMutex = new KviMutex(); -#ifdef COMPILE_SSL_SUPPORT -// qDebug("CLEARING SSL IN KviDccThread constructor"); - m_pSSL = 0; -#endif -} - -KviDccThread::~KviDccThread() -{ -#ifdef COMPILE_SSL_SUPPORT - if(m_pSSL)KviSSLMaster::freeSSL(m_pSSL); - m_pSSL = 0; -#endif - if(m_fd != KVI_INVALID_SOCKET)kvi_socket_close(m_fd); - KVI_ASSERT(!m_pMutex->locked()); - delete m_pMutex; -} - -#ifdef COMPILE_SSL_SUPPORT -void KviDccThread::setSSL(KviSSL * s) -{ - if(m_pSSL)KviSSLMaster::freeSSL(m_pSSL); - m_pSSL = s; -} -#endif - -bool KviDccThread::handleInvalidSocketRead(int readLen) -{ - KVI_ASSERT(readLen < 1); - if(readLen == 0) - { - // connection closed - postErrorEvent(KviError::RemoteEndClosedConnection); - return false; - } else { - // error ? - int err = kvi_socket_error(); - if((err != EINTR) && (err != EAGAIN)) - { - postErrorEvent(KviError::translateSystemError(err)); - return false; - } - } - return true; // continue -} - -#ifdef COMPILE_SSL_SUPPORT -void KviDccThread::raiseSSLError() -{ - KviCString buffer; - while(m_pSSL->getLastErrorString(buffer)) - { - KviCString msg(KviCString::Format,"[SSL ERROR]: %s",buffer.ptr()); - postMessageEvent(msg.ptr()); - } -} -#endif - -void KviDccThread::postErrorEvent(int err) -{ - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ERROR); - e->setData(new int(err)); - postEvent(m_pParent,e); -} - -void KviDccThread::postMessageEvent(const char * message) -{ - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_MESSAGE); - e->setData(new KviCString(message)); - postEvent(m_pParent,e); -} diff --git a/src/modules/dcc/thread.h b/src/modules/dcc/thread.h deleted file mode 100644 index 03a981b55..000000000 --- a/src/modules/dcc/thread.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef _THREAD_H_ -#define _THREAD_H_ -//============================================================================= -// -// File : thread.h -// Creation date : Tue Sep 20 09 2000 18:28:44 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "kvi_settings.h" -#include "KviThread.h" -#include "kvi_sockettype.h" -#include "KviPointerList.h" - -#include - -#ifdef COMPILE_SSL_SUPPORT - #include "KviSSL.h" -#endif - -// KviThreadDataEvent -#define KVI_DCC_THREAD_EVENT_ERROR (KVI_THREAD_USER_EVENT_BASE + 1) -// KviThreadDataEvent -#define KVI_DCC_THREAD_EVENT_DATA (KVI_THREAD_USER_EVENT_BASE + 2) -// KviThreadEvent -#define KVI_DCC_THREAD_EVENT_SUCCESS (KVI_THREAD_USER_EVENT_BASE + 3) -// KviThreadDataEvent -#define KVI_DCC_THREAD_EVENT_MESSAGE (KVI_THREAD_USER_EVENT_BASE + 4) -// KviThreadDataEvent -#define KVI_DCC_THREAD_EVENT_ACTION (KVI_THREAD_USER_EVENT_BASE + 5) - -typedef struct _KviDccThreadIncomingData -{ - int iLen; - char * buffer; -} KviDccThreadIncomingData; - -class KviDccThread : public KviSensitiveThread -{ -public: - KviDccThread(QObject * par,kvi_socket_t fd); - ~KviDccThread(); -protected: - KviMutex * m_pMutex; // OWNED! PROTECTS m_pOutBuffers - kvi_socket_t m_fd; - QObject * m_pParent; // READ ONLY! -#ifdef COMPILE_SSL_SUPPORT - KviSSL * m_pSSL; -#endif -protected: - bool handleInvalidSocketRead(int readLen); -public: - QObject * parent(){ return m_pParent; }; - void postErrorEvent(int err); - // Warning!..newer call __tr() here!...use __tr_no_lookup() - void postMessageEvent(const char * message); -#ifdef COMPILE_SSL_SUPPORT - void raiseSSLError(); - void setSSL(KviSSL * s); - KviSSL * getSSL() const { return m_pSSL; }; -#endif -}; - -#endif //_THREAD_H_ diff --git a/src/modules/dcc/utils.cpp b/src/modules/dcc/utils.cpp deleted file mode 100644 index 8817bc0fa..000000000 --- a/src/modules/dcc/utils.cpp +++ /dev/null @@ -1,170 +0,0 @@ -//============================================================================= -// -// File : utils.cpp -// Creation date : Tue Jul 23 02:54:44 2002 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#define _UTILS_CPP_ - -#include "utils.h" - -#include "KviOptions.h" -#include "KviLocale.h" -#include "KviNetUtils.h" -#include "KviIrcSocket.h" -#include "KviIrcLink.h" -#include "KviQString.h" - -/* -bool dcc_module_get_listen_ip_address(KviCommand *c,KviConsoleWindow * pConsole,QString &szListenIp) -{ - // - // Find an interface suitable for listening.... - // Either from user options or from the current connection... - // - - if(KVI_OPTION_BOOL(KviOption_boolDccListenOnSpecifiedInterfaceByDefault)) - { - KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).trimmed(); - if(!KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).isEmpty()) - { - if(kvi_isValidStringIp(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).toUtf8().data())) - { - if(KviQString::equalCI(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface),"0.0.0.0")) - { - // Try to find the first available IPv4 interface - if(!kvi_getLocalHostAddress(szListenIp)) - { - if(c)c->warning(__tr2qs_ctx("Can't retrieve a suitable local IPV4 address","dcc"), - KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).toUtf8().data()); - return false; - } - } else { - szListenIp = KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface); - } - return true; - } -#ifdef COMPILE_IPV6_SUPPORT - if(kvi_isValidStringIPv6(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).toUtf8().data())) - { - szListenIp = KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface); - } else { -#endif - if(!kvi_getInterfaceAddress(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).toUtf8().data(),szListenIp)) - { - KVI_OPTION_BOOL(KviOption_boolDccListenOnSpecifiedInterfaceByDefault) = false; - if(c)c->warning(__tr2qs_ctx("Can't listen on default interface '%s': fix it in the options dialog, disabling the option (so the next dcc will work)","dcc"), - KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).toUtf8().data()); - return false; - } -#ifdef COMPILE_IPV6_SUPPORT - } -#endif - return true; - } else { - // the option was empty.. disable it - KVI_OPTION_BOOL(KviOption_boolDccListenOnSpecifiedInterfaceByDefault) = false; - } - } - - if(pConsole) - { - if(pConsole->isConnected()) - { - //#warning "The IPV6 choice is not OK here.... and maybe allow to bind to specified ports" - pConsole->socket()->getLocalHostIp(szListenIp,pConsole->isIPv6Connection()); - } else { - szListenIp = "0.0.0.0"; // huh ? :) - } - } else { - szListenIp = "0.0.0.0"; - } - - return true; -} -*/ - -bool dcc_kvs_get_listen_ip_address(KviKvsModuleCommandCall *c,KviConsoleWindow * pConsole,QString &szListenIp) -{ - // - // Find an interface suitable for listening.... - // Either from user options or from the current connection... - // - - if(KVI_OPTION_BOOL(KviOption_boolDccListenOnSpecifiedInterfaceByDefault)) - { - KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).trimmed(); - if(!KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).isEmpty()) - { - if(KviNetUtils::isValidStringIp(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).toUtf8().data())) - { - if(KviQString::equalCI(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface),"0.0.0.0")) - { - // Try to find the first available IPv4 interface - if(!kvi_getLocalHostAddress(szListenIp)) - { - if(c)c->warning(__tr2qs_ctx("Can't retrieve a suitable local IPV4 address","dcc"), - KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).toUtf8().data()); - return false; - } - } else { - szListenIp = KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface); - } - return true; - } -#ifdef COMPILE_IPV6_SUPPORT - if(KviNetUtils::isValidStringIPv6(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).toUtf8().data())) - { - szListenIp = KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface); - } else { -#endif - if(!KviNetUtils::getInterfaceAddress(KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface),szListenIp)) - { - KVI_OPTION_BOOL(KviOption_boolDccListenOnSpecifiedInterfaceByDefault) = false; - if(c)c->warning(__tr2qs_ctx("Can't listen on default interface '%s': fix it in the options dialog, disabling the option (so the next dcc will work)","dcc"), - KVI_OPTION_STRING(KviOption_stringDccListenDefaultInterface).toUtf8().data()); - return false; - } -#ifdef COMPILE_IPV6_SUPPORT - } -#endif - return true; - } else { - // the option was empty.. disable it - KVI_OPTION_BOOL(KviOption_boolDccListenOnSpecifiedInterfaceByDefault) = false; - } - } - - if(pConsole) - { - if(pConsole->isConnected()) - { - //#warning "The IPV6 choice is not OK here.... and maybe allow to bind to specified ports" - pConsole->connection()->link()->socket()->getLocalHostIp(szListenIp,pConsole->isIPv6Connection()); - } else { - szListenIp = "0.0.0.0"; // huh ? :) - } - } else { - szListenIp = "0.0.0.0"; - } - - return true; -} diff --git a/src/modules/dcc/utils.h b/src/modules/dcc/utils.h deleted file mode 100644 index b201a7142..000000000 --- a/src/modules/dcc/utils.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef _UTILS_H_ -#define _UTILS_H_ -//============================================================================= -// -// File : utils.h -// Creation date : Tue Jul 23 02:54:45 2002 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "kvi_settings.h" -#include "KviCString.h" -#include "KviConsoleWindow.h" -#include "KviKvsModuleInterface.h" - -#ifndef _UTILS_CPP_ - extern bool dcc_kvs_get_listen_ip_address(KviKvsModuleCommandCall *c,KviConsoleWindow * pConsole,QString &szListenIp); -#endif - -#endif //_UTILS_H_ diff --git a/src/modules/dcc/video.cpp b/src/modules/dcc/video.cpp deleted file mode 100644 index 987ba5cd1..000000000 --- a/src/modules/dcc/video.cpp +++ /dev/null @@ -1,1032 +0,0 @@ -//============================================================================= -// -// File : video.cpp -// Creation date : Tue Nov 10 18:08:09 2009 GMT by Fabio Bas -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2009 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "kvi_settings.h" - -#include "video.h" -#include "marshal.h" -#include "broker.h" - -#include "KviIconManager.h" -#include "KviIrcView.h" -#include "KviKvsEventTriggers.h" -#include "KviLocale.h" -#include "kvi_out.h" -#include "KviNetUtils.h" -#include "KviOptions.h" -#include "KviConsoleWindow.h" -#include "KviMemory.h" -#include "kvi_socket.h" -#include "KviIrcConnection.h" -#include "KviTalVBox.h" -#include "KviMircCntrl.h" -#include "KviMainWindow.h" - -#include -#include -#include -#include //for Qt::escape - -#ifdef COMPILE_CRYPT_SUPPORT - #include "KviCryptController.h" -#endif - -#ifdef COMPILE_SSL_SUPPORT - #include "KviSSLMaster.h" -#endif - -#include - -#define FRAME_DURATION 200 // 1 / 5fps = 200msec - -extern KviDccBroker * g_pDccBroker; - -#ifndef COMPILE_DISABLE_DCC_VIDEO - Kopete::AV::VideoDevicePool *g_pVideoDevicePool=0; - int g_iVideoDevicePoolInstances=0; -#endif - -bool kvi_dcc_video_is_valid_codec(const char * codecName) -{ - if(kvi_strEqualCI("sjpeg",codecName))return true; -#ifndef COMPILE_DISABLE_OGG_THEORA - if(kvi_strEqualCI("theora",codecName))return true; -#endif - return false; -} - -static KviDccVideoCodec * kvi_dcc_video_get_codec(const char *codecName) -{ -#ifndef COMPILE_DISABLE_OGG_THEORA - if(kvi_strEqualCI("theora",codecName))return new KviDccVideoTheoraCodec(); -#endif - return new KviDccVideoSJpegCodec(); -} - - -KviDccVideoThread::KviDccVideoThread(KviWindow * wnd,kvi_socket_t fd,KviDccVideoThreadOptions * opt) -: KviDccThread(wnd,fd) -{ -#ifndef COMPILE_DISABLE_DCC_VIDEO - m_pOpt = opt; - m_bPlaying = false; - m_bRecording = false; - - //local video input - if(!g_pVideoDevicePool) - { - g_pVideoDevicePool = Kopete::AV::VideoDevicePool::self(); - g_pVideoDevicePool->open(); - g_pVideoDevicePool->setSize(320, 240); - } - g_iVideoDevicePoolInstances++; - //ensure capturing - g_pVideoDevicePool->startCapturing(); -#endif - startRecording(); - startPlaying(); - -} - -KviDccVideoThread::~KviDccVideoThread() -{ - stopRecording(); -#ifndef COMPILE_DISABLE_DCC_VIDEO - g_iVideoDevicePoolInstances--; - if(g_iVideoDevicePoolInstances==0) - g_pVideoDevicePool->close(); - - delete m_pOpt->pCodec; - delete m_pOpt; -#endif -} - -bool KviDccVideoThread::readWriteStep() -{ -// qDebug("KviDccVideoThread::readWriteStep()"); -#ifndef COMPILE_DISABLE_DCC_VIDEO - // Socket management - bool bCanRead; - bool bCanWrite; - - if(kvi_select(m_fd,&bCanRead,&bCanWrite)) - { - while(bCanRead) - { - unsigned int actualSize = m_inFrameBuffer.size(); - m_inFrameBuffer.resize(actualSize + 16384); - int readLen = kvi_socket_recv(m_fd,(void *)(m_inFrameBuffer.data() + actualSize),16384); - if(readLen > 0) - { - if(readLen < 16384)m_inFrameBuffer.resize(actualSize + readLen); - m_pOpt->pCodec->decode(&m_inFrameBuffer,&m_videoInSignalBuffer,&m_textInSignalBuffer); - } else { - bCanRead=false; -// if(!handleInvalidSocketRead(readLen))return false; - m_inFrameBuffer.resize(actualSize); - } - } - - if(bCanWrite) - { - // Have somethihg to write ? - if(m_outFrameBuffer.size() > 0) - { - int written = kvi_socket_send(m_fd,m_outFrameBuffer.data(),m_outFrameBuffer.size()); - if(written > 0) - { - m_outFrameBuffer.remove(written); - } else { - if(!handleInvalidSocketRead(written))return false; - } - } - } - } -#endif // !COMPILE_DISABLE_DCC_VOICE - return true; -} - -bool KviDccVideoThread::videoStep() -{ -// qDebug("KviDccVideoThread::videoStep()"); -#ifndef COMPILE_DISABLE_DCC_VIDEO - // Are we playing ? - if(m_bPlaying) - { - if(m_videoInSignalBuffer.size() > 0) - { - QImage img(m_videoInSignalBuffer.data(), 320, 240, 1280, QImage::Format_ARGB32); -// qDebug("IMG data %p size %d", m_videoInSignalBuffer.data(), m_videoInSignalBuffer.size()); - if(!img.isNull()) - m_inImage = img; - } - } - - // Are we recording ? - if(m_bRecording) - { - //grab the image, compress using the codec - g_pVideoDevicePool->getFrame(); - g_pVideoDevicePool->getImage(&m_outImage); - if(m_outImage.numBytes() > 0) - { - m_videoOutSignalBuffer.append((const unsigned char*) m_outImage.bits(), m_outImage.numBytes()); - m_pOpt->pCodec->encodeVideo(&m_videoOutSignalBuffer,&m_outFrameBuffer); - } - } - -#endif // !COMPILE_DISABLE_DCC_VIDEO - return true; -} - -bool KviDccVideoThread::textStep() -{ -// qDebug("KviDccVideoThread::textStep()"); -#ifndef COMPILE_DISABLE_DCC_VIDEO - // Are we playing ? - if(m_bPlaying) - { - if(m_textInSignalBuffer.size() > 0) - { - KviDccThreadIncomingData data; - data.iLen = m_textInSignalBuffer.size(); - data.buffer = (char*) KviMemory::allocate(data.iLen); - memcpy(data.buffer, m_textInSignalBuffer.data(), data.iLen); - handleIncomingData(&data,false); - - m_textInSignalBuffer.clear(); - } - } - - // Are we recording ? - if(m_bRecording) - { - if(((KviDccVideo*)parent())->m_tmpTextDataOut.size()) - { - m_textOutSignalBuffer.append((const unsigned char*) ((KviDccVideo*)parent())->m_tmpTextDataOut.constData(), ((KviDccVideo*)parent())->m_tmpTextDataOut.size()); - ((KviDccVideo*)parent())->m_tmpTextDataOut.clear(); - } - - if(m_textOutSignalBuffer.size()) - m_pOpt->pCodec->encodeText(&m_textOutSignalBuffer,&m_outFrameBuffer); - } - -#endif // !COMPILE_DISABLE_DCC_VIDEO - return true; -} - -bool KviDccVideoThread::handleIncomingData(KviDccThreadIncomingData * data,bool bCritical) -{ -// qDebug("KviDccVideoThread::handleIncomingData"); - KVI_ASSERT(data->iLen); - KVI_ASSERT(data->buffer); - char * aux = data->buffer; - char * end = data->buffer + data->iLen; - while(aux != end) - { - if((*aux == '\n') || (*aux == '\0')) - { - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_DATA); - // The left part is len chars long - int len = aux - data->buffer; -// qDebug("LEN = %d, iLen = %d",len,data->iLen); -//#warning "DO IT BETTER (the \r cutting)" - KviCString * s = new KviCString(data->buffer,len); - if(s->lastCharIs('\r'))s->cutRight(1); - e->setData(s); - // but we cut also \n (or \0) - ++aux; - // so len += 1; --> new data->iLen -= len; - data->iLen -= (len + 1); -// qDebug("iLen now = %d",data->iLen); - KVI_ASSERT(data->iLen >= 0); - if(data->iLen > 0) - { - // memmove the remaining part to the beginning - // aux points after \n or \0 - KviMemory::move(data->buffer,aux,data->iLen); - data->buffer = (char *)KviMemory::reallocate(data->buffer,data->iLen); - end = data->buffer + data->iLen; - aux = data->buffer; - } else { - // no more data in the buffer - KVI_ASSERT(data->iLen == 0); - KviMemory::free(data->buffer); - data->buffer = end = aux = 0; - } - postEvent(parent(),e); - } else aux++; -// qDebug("PASSING CHAR %c",*aux); - } - // now aux == end - if(bCritical) - { - // need to flush everything... - if(data->iLen > 0) - { - // in the last part there are no NULL and \n chars - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_DATA); - KviCString * s = new KviCString(data->buffer,data->iLen); - if(s->lastCharIs('\r'))s->cutRight(1); - e->setData(s); - data->iLen = 0; - KviMemory::free(data->buffer); - data->buffer = 0; - postEvent(parent(),e); - } - } - return true; -} - -void KviDccVideoThread::restartRecording(int iDevice, int iInput, int) -{ -#ifndef COMPILE_DISABLE_DCC_VIDEO - m_bRecording=false; - if(!g_pVideoDevicePool) - g_pVideoDevicePool = Kopete::AV::VideoDevicePool::self(); - - g_pVideoDevicePool->stopCapturing(); - g_pVideoDevicePool->open(iDevice); - g_pVideoDevicePool->setSize(320, 240); - if(iInput >= 0) - g_pVideoDevicePool->selectInput(iInput); - g_pVideoDevicePool->startCapturing(); - - m_bRecording=true; -#endif -} - -void KviDccVideoThread::startRecording() -{ -#ifndef COMPILE_DISABLE_DCC_VIDEO - //qDebug("Start recording"); - if(m_bRecording)return; // already started - -// qDebug("Posting event"); - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); - e->setData(new int(KVI_DCC_VIDEO_THREAD_ACTION_START_RECORDING)); - postEvent(KviDccThread::parent(),e); - - m_bRecording = true; -#endif -} - -void KviDccVideoThread::stopRecording() -{ -#ifndef COMPILE_DISABLE_DCC_VIDEO - //qDebug("Stop recording"); - if(!m_bRecording)return; // already stopped - - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); - e->setData(new int(KVI_DCC_VIDEO_THREAD_ACTION_STOP_RECORDING)); - postEvent(KviDccThread::parent(),e); - - m_bRecording = false; -#endif -} - -void KviDccVideoThread::startPlaying() -{ -#ifndef COMPILE_DISABLE_DCC_VIDEO - //qDebug("Start playing"); - if(m_bPlaying)return; - - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); - e->setData(new int(KVI_DCC_VIDEO_THREAD_ACTION_START_PLAYING)); - postEvent(KviDccThread::parent(),e); - m_bPlaying = true; - -#endif -} - -void KviDccVideoThread::stopPlaying() -{ -#ifndef COMPILE_DISABLE_DCC_VIDEO - //qDebug("Stop playing"); - if(!m_bPlaying)return; - - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); - e->setData(new int(KVI_DCC_VIDEO_THREAD_ACTION_STOP_PLAYING)); - postEvent(KviDccThread::parent(),e); - m_bPlaying = false; -#endif -} - -void KviDccVideoThread::run() -{ -// qDebug("KviDccVideoThread::run()"); -#ifndef COMPILE_DISABLE_DCC_VIDEO - for(;;) - { - // Dequeue events - while(KviThreadEvent * e = dequeueEvent()) - { - if(e->id() == KVI_THREAD_EVENT_TERMINATE) - { - delete e; - goto exit_dcc; - } else if(e->id() == KVI_DCC_THREAD_EVENT_ACTION) - { - int * act = ((KviThreadDataEvent *)e)->getData(); - if(*act)startRecording(); - else stopRecording(); - delete act; - delete e; - } else { - // Other events are senseless to us - delete e; - } - } - - if(!readWriteStep())goto exit_dcc; - if(!videoStep())goto exit_dcc; - if(!textStep())goto exit_dcc; - - usleep(FRAME_DURATION*1000); -// qDebug("in %d out %d in_sig %d out_sig %d", m_inFrameBuffer.size(), m_outFrameBuffer.size(), m_videoInSignalBuffer.size(), m_videoOutSignalBuffer.size()); - } - - -exit_dcc: - -#endif //! COMPILE_DISABLE_DCC_VIDEO - kvi_socket_close(m_fd); - m_fd = KVI_INVALID_SOCKET; -} - -KviDccVideo::KviDccVideo(KviMainWindow *pFrm,KviDccDescriptor * dcc,const char * name) -: KviDccWindow(KVI_WINDOW_TYPE_DCCVIDEO,pFrm,name,dcc) -{ - m_pDescriptor = dcc; - m_pSlaveThread = 0; - m_pszTarget = 0; - - m_pLayout = new QGridLayout(this); - - m_pButtonBox = new KviTalHBox(this); - - m_pLabel = new KviThemedLabel(m_pButtonBox, this, "dcc_chat_label"); - m_pLabel->setText(name); - m_pButtonBox->setStretchFactor(m_pLabel,1); - - m_pButtonContainer= new KviTalHBox(m_pButtonBox); - createTextEncodingButton(m_pButtonContainer); - -#ifdef COMPILE_CRYPT_SUPPORT - createCryptControllerButton(m_pButtonContainer); -#endif - m_pLayout->addWidget(m_pButtonBox, 0, 0, 1, 3); - - m_pIrcView = new KviIrcView(this,pFrm,this); - connect(m_pIrcView,SIGNAL(rightClicked()),this,SLOT(textViewRightClicked())); - m_pInput = new KviInput(this); - - //remote video - m_pInVideoLabel = new QLabel(); - m_pInVideoLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - m_pInVideoLabel->setMinimumSize(320, 240); - m_pInVideoLabel->setFrameShape(QFrame::Box); - m_pInVideoLabel->setScaledContents(true); - m_pInVideoLabel->setAlignment(Qt::AlignCenter); - m_pLayout->addWidget(m_pInVideoLabel, 1, 0, 6, 1); - - //local video - m_pOutVideoLabel = new QLabel(); - m_pOutVideoLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - m_pOutVideoLabel->setMinimumSize(320, 240); - m_pOutVideoLabel->setFrameShape(QFrame::Box); - m_pOutVideoLabel->setScaledContents(true); - m_pOutVideoLabel->setAlignment(Qt::AlignCenter); - m_pLayout->addWidget(m_pOutVideoLabel, 1, 1, 6, 1); - - //local video input: config - m_pVideoLabel[0] = new QLabel(); - m_pVideoLabel[0]->setText(__tr2qs_ctx("Video device:","dcc")); - m_pLayout->addWidget(m_pVideoLabel[0], 1, 2, 1, 1); - - m_pCDevices = new QComboBox(); - m_pLayout->addWidget(m_pCDevices, 2, 2, 1, 1); - - m_pVideoLabel[1] = new QLabel(); - m_pVideoLabel[1]->setText(__tr2qs_ctx("Input:","dcc")); - m_pLayout->addWidget(m_pVideoLabel[1], 3, 2, 1, 1); - - m_pCInputs = new QComboBox(); - m_pLayout->addWidget(m_pCInputs, 4, 2, 1, 1); - - m_pVideoLabel[2] = new QLabel(); - m_pVideoLabel[2]->setText(__tr2qs_ctx("Standard:","dcc")); - m_pLayout->addWidget(m_pVideoLabel[2], 5, 2, 1, 1); - - m_pCStandards = new QComboBox(); - m_pLayout->addWidget(m_pCStandards, 6, 2, 1, 1); - - m_pLayout->addWidget(m_pIrcView, 7, 0, 1, 3); - m_pLayout->addWidget(m_pInput, 8, 0, 1, 3); - m_pLayout->setRowStretch(7,1); - - setLayout(m_pLayout); - - if(KVI_OPTION_BOOL(KviOption_boolAutoLogDccChat))m_pIrcView->startLogging(); - - connect(&m_Timer, SIGNAL(timeout()), this, SLOT(slotUpdateImage()) ); - - m_Timer.start(FRAME_DURATION); - - m_pMarshal = new KviDccMarshal(this); - connect(m_pMarshal,SIGNAL(error(int)),this,SLOT(handleMarshalError(int))); - connect(m_pMarshal,SIGNAL(connected()),this,SLOT(connected())); - connect(m_pMarshal,SIGNAL(inProgress()),this,SLOT(connectionInProgress())); - - connect(m_pCDevices, SIGNAL(currentIndexChanged(int)), this, SLOT(videoInputChanged(int))); - connect(m_pCInputs, SIGNAL(currentIndexChanged(int)), this, SLOT(videoInputChanged(int))); - connect(m_pCStandards, SIGNAL(currentIndexChanged(int)), this, SLOT(videoInputChanged(int))); - - startConnection(); -} - -KviDccVideo::~KviDccVideo() -{ - if(m_pInVideoLabel) - { - delete m_pInVideoLabel; - m_pInVideoLabel=0; - } - if(m_pOutVideoLabel) - { - delete m_pOutVideoLabel; - m_pOutVideoLabel=0; - } - if(m_pCDevices) - { - delete m_pCDevices; - m_pCDevices=0; - } - if(m_pCInputs) - { - delete m_pCInputs; - m_pCInputs=0; - } - if(m_pCStandards) - { - delete m_pCStandards; - m_pCStandards=0; - } - if(m_pVideoLabel[0]) - { - delete m_pVideoLabel[2]; - delete m_pVideoLabel[1]; - delete m_pVideoLabel[0]; - m_pVideoLabel[2] = 0; - m_pVideoLabel[1] = 0; - m_pVideoLabel[0] = 0; - } - if(m_pLayout) - { - delete m_pLayout; - m_pLayout=0; - } - - g_pDccBroker->unregisterDccWindow(this); - - if(m_pSlaveThread) - { - m_pSlaveThread->terminate(); - delete m_pSlaveThread; - m_pSlaveThread = 0; - } - - KviThreadManager::killPendingEvents(this); - - if(m_pszTarget) - { - delete m_pszTarget; - m_pszTarget = 0; - } -} - -void KviDccVideo::textViewRightClicked() -{ - KVS_TRIGGER_EVENT_1(KviEvent_OnDCCChatPopupRequest,this,m_pDescriptor->idString()); -} - -void KviDccVideo::triggerCreationEvents() -{ - KVS_TRIGGER_EVENT_1(KviEvent_OnDCCChatWindowCreated,this,m_pDescriptor->idString()); -} - -void KviDccVideo::triggerDestructionEvents() -{ - KVS_TRIGGER_EVENT_1(KviEvent_OnDCCChatWindowClosing,this,m_pDescriptor->idString()); -} - -void KviDccVideo::startConnection() -{ - if(!(m_pDescriptor->bActive)) - { - // PASSIVE CONNECTION - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Attempting a passive DCC VIDEO connection","dcc")); - KviError::Code eError = m_pMarshal->dccListen(m_pDescriptor->szListenIp,m_pDescriptor->szListenPort,m_pDescriptor->bDoTimeout); - if(eError != KviError::Success) - handleMarshalError(eError); - } else { - // ACTIVE CONNECTION - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Attempting an active DCC VIDEO connection","dcc")); - KviError::Code eError = m_pMarshal->dccConnect(m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data(),m_pDescriptor->bDoTimeout); - if(eError != KviError::Success) - handleMarshalError(eError); - } -} - -void KviDccVideo::connectionInProgress() -{ - if(m_pDescriptor->bActive) - { - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Contacting host %Q on port %Q","dcc"),&(m_pDescriptor->szIp),&(m_pDescriptor->szPort)); - } else { - - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Listening on interface %Q port %Q","dcc"), - &(m_pMarshal->localIp()),&(m_pMarshal->localPort())); - - if(m_pDescriptor->bSendRequest) - { - QString ip = !m_pDescriptor->szFakeIp.isEmpty() ? m_pDescriptor->szFakeIp : m_pDescriptor->szListenIp; - KviCString port = !m_pDescriptor->szFakePort.isEmpty() ? m_pDescriptor->szFakePort : m_pMarshal->localPort(); -//#warning "OPTION FOR SENDING 127.0.0.1 and so on (not an unsigned nuumber)" - struct in_addr a; - if(KviNetUtils::stringIpToBinaryIp(ip,&a)) { - ip.setNum(htonl(a.s_addr)); - } - - m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC VIDEO %s %Q %s %d%c", - m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(), - 0x01,m_pDescriptor->szCodec.ptr(), - &ip,port.ptr(),m_pDescriptor->iSampleRate,0x01); - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Sent DCC VIDEO (%s) request to %Q, waiting for the remote client to connect...","dcc"), - m_pDescriptor->szCodec.ptr(),&(m_pDescriptor->szNick)); - } else output(KVI_OUT_DCCMSG,__tr2qs_ctx("DCC VIDEO request not sent: awaiting manual connection","dcc")); - } -} - -const QString & KviDccVideo::target() -{ - // This may change on the fly... - if(!m_pszTarget) - m_pszTarget = new QString(); - - m_pszTarget->sprintf("%s@%s:%s",m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data()); - return *m_pszTarget; -} - -void KviDccVideo::getBaseLogFileName(QString &buffer) -{ - buffer.sprintf("dccvideo_%s_%s_%s",m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szLocalFileName.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data()); -} - -void KviDccVideo::fillCaptionBuffers() -{ - KviCString tmp(KviCString::Format,"DCC Video %s@%s:%s %s", - m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data(), - m_pDescriptor->szLocalFileName.toUtf8().data()); - - m_szPlainTextCaption = tmp; -} - -QPixmap * KviDccVideo::myIconPtr() -{ - return g_pIconManager->getSmallIcon(KVI_SMALLICON_DCCVOICE); -} - -void KviDccVideo::ownMessage(const QString &text, bool bUserFeedback) -{ - if(!m_pSlaveThread) - { - output(KVI_OUT_SYSTEMWARNING,__tr2qs_ctx("Cannot send data: No active connection","dcc")); - return; - } - - QByteArray szData = encodeText(text); - const char * d = szData.data(); - if(!d)return; - -#ifdef COMPILE_CRYPT_SUPPORT - if(cryptSessionInfo()) - { - if(cryptSessionInfo()->m_bDoEncrypt) - { - if(*d != KviMircCntrl::CryptEscape) - { - KviCString encrypted; - cryptSessionInfo()->m_pEngine->setMaxEncryptLen(-1); - switch(cryptSessionInfo()->m_pEngine->encrypt(d,encrypted)) - { - case KviCryptEngine::Encrypted: - { - KviCString buf(KviCString::Format,"%s\r\n",encrypted.ptr()); - m_tmpTextDataOut.append(buf.ptr(), buf.len()); - if(bUserFeedback) - m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSGCRYPTED, - m_pDescriptor->szLocalNick.toUtf8().data(),m_pDescriptor->szLocalUser.toUtf8().data(), - m_pDescriptor->szLocalHost.toUtf8().data(),text,KviConsoleWindow::NoNotifications); - } - break; - case KviCryptEngine::Encoded: - { - KviCString buf(KviCString::Format,"%s\r\n",encrypted.ptr()); - m_tmpTextDataOut.append(buf.ptr(), buf.len()); - if(bUserFeedback) - { - QString encr = decodeText(encrypted.ptr()); - m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG, - m_pDescriptor->szLocalNick.toUtf8().data(),m_pDescriptor->szLocalUser.toUtf8().data(), - m_pDescriptor->szLocalHost.toUtf8().data(),encr,KviConsoleWindow::NoNotifications); - } - } - break; - default: // also case KviCryptEngine::EncryptError - { - QString szErr = cryptSessionInfo()->m_pEngine->lastError(); - output(KVI_OUT_SYSTEMERROR, - __tr2qs_ctx("The crypto engine was not able to encrypt the current message (%Q): %Q, no data was sent to the remote end","dcc"), - &text,&szErr); - } - break; - } - return; - } else { - d++; //eat the escape code - KviCString buf(KviCString::Format,"%s\r\n",d); - QString tmp = text.right(text.length() - 1); - m_tmpTextDataOut.append(buf.ptr(), buf.len()); - - if(bUserFeedback) - m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG, - m_pDescriptor->szLocalNick.toUtf8().data(),m_pDescriptor->szLocalUser.toUtf8().data(), - m_pDescriptor->szLocalHost.toUtf8().data(),tmp,KviConsoleWindow::NoNotifications); - return; - } - } - } -#endif - KviCString buf(KviCString::Format,"%s\r\n",d); - m_tmpTextDataOut.append(buf.ptr(), buf.len()); - - if(bUserFeedback) - m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG, - m_pDescriptor->szLocalNick.toUtf8().data(),m_pDescriptor->szLocalUser.toUtf8().data(), - m_pDescriptor->szLocalHost.toUtf8().data(),text,KviConsoleWindow::NoNotifications); -} - -const QString & KviDccVideo::localNick() -{ - // FIXME: This is just a complete HACK - m_szLocalNick = m_pDescriptor->szLocalNick; - return m_szLocalNick; -} - -void KviDccVideo::ownAction(const QString &text) -{ - if(m_pSlaveThread) - { - QString szTmpBuffer; - //see bug ticket #220 - if(KVI_OPTION_BOOL(KviOption_boolStripMircColorsInUserMessages)) - { - szTmpBuffer = KviMircCntrl::stripControlBytes(text); - } else { - szTmpBuffer = text; - } - - QByteArray szData = encodeText(szTmpBuffer); - const char * d = szData.data(); - if(!d)return; - KviCString buf(KviCString::Format,"%cACTION %s%c\r\n",0x01,d,0x01); - m_tmpTextDataOut.append(buf.ptr(), buf.len()); - output(KVI_OUT_ACTION,"%Q %Q",&(m_pDescriptor->szLocalNick),&szTmpBuffer); - } else { - output(KVI_OUT_SYSTEMWARNING,__tr2qs_ctx("Cannot send data: No active connection","dcc")); - } -} - -bool KviDccVideo::event(QEvent *e) -{ - if(e->type() == KVI_THREAD_EVENT) - { - switch(((KviThreadEvent *)e)->id()) - { - case KVI_DCC_THREAD_EVENT_ERROR: - { - KviError::Code * pError = ((KviThreadDataEvent *)e)->getData(); - QString ssss = KviError::getDescription(*pError); - output(KVI_OUT_DCCERROR,__tr2qs_ctx("ERROR: %Q","dcc"),&(ssss)); - delete pError; - return true; - } - break; - case KVI_DCC_THREAD_EVENT_DATA: - { - KviCString * encoded = ((KviThreadDataEvent *)e)->getData(); - KviCString d=KviCString(decodeText(encoded->ptr())); - if(d.firstCharIs(0x01)) - { - d.cutLeft(1); - if(d.lastCharIs(0x01)) - d.cutRight(1); - if(kvi_strEqualCIN("ACTION",d.ptr(),6)) - d.cutLeft(6); - d.stripLeftWhiteSpace(); - output(KVI_OUT_ACTION,"%Q %s",&(m_pDescriptor->szNick),d.ptr()); - if(!hasAttention()) - { - if(KVI_OPTION_BOOL(KviOption_boolFlashDccChatWindowOnNewMessages)) - { - demandAttention(); - } - if(KVI_OPTION_BOOL(KviOption_boolPopupNotifierOnNewDccChatMessages)) - { - QString szMsg = ""; - szMsg += m_pDescriptor->szNick; - szMsg += " "; - szMsg += Qt::escape(QString(d.ptr())); - //qDebug("KviIrcServerParser_ctcp.cpp:975 debug: %s",szMsg.data()); - g_pApp->notifierMessage(this,KVI_OPTION_MSGTYPE(KVI_OUT_ACTION).pixId(),szMsg,KVI_OPTION_UINT(KviOption_uintNotifierAutoHideTime)); - } - } - } else { - -#ifdef COMPILE_CRYPT_SUPPORT - if(KviCryptSessionInfo * cinf = cryptSessionInfo()) - { - if(cinf->m_bDoDecrypt) - { - KviCString decryptedStuff; - switch(cinf->m_pEngine->decrypt(d.ptr(),decryptedStuff)) - { - case KviCryptEngine::DecryptOkWasEncrypted: - case KviCryptEngine::DecryptOkWasEncoded: - case KviCryptEngine::DecryptOkWasPlainText: - if(!KVS_TRIGGER_EVENT_2_HALTED(KviEvent_OnDCCChatMessage,this,QString(decryptedStuff.ptr()),m_pDescriptor->idString())) - { - m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG, - m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szUser.toUtf8().data(), - m_pDescriptor->szHost.toUtf8().data(),decryptedStuff.ptr()); - } - delete encoded; - return true; - break; - - default: // also case KviCryptEngine::DecryptError - { - QString szErr = cinf->m_pEngine->lastError(); - output(KVI_OUT_SYSTEMERROR, - __tr2qs_ctx("The following message appears to be encrypted, but the crypto engine failed to decode it: %Q","dcc"), - &szErr); - } - break; - } - } - } else { -#endif - // FIXME! - if(!KVS_TRIGGER_EVENT_2_HALTED(KviEvent_OnDCCChatMessage,this,QString(d.ptr()),m_pDescriptor->idString())) - { - m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG, - m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szUser.toUtf8().data(), - m_pDescriptor->szHost.toUtf8().data(),d.ptr()); - if(!hasAttention()) - { - if(KVI_OPTION_BOOL(KviOption_boolFlashDccChatWindowOnNewMessages)) - { - demandAttention(); - } - if(KVI_OPTION_BOOL(KviOption_boolPopupNotifierOnNewDccChatMessages)) - { - QString szMsg = Qt::escape(QString(d.ptr())); - g_pApp->notifierMessage(this,KVI_SMALLICON_DCCCHATMSG,szMsg,KVI_OPTION_UINT(KviOption_uintNotifierAutoHideTime)); - } - } - } -#ifdef COMPILE_CRYPT_SUPPORT - } -#endif - } - delete encoded; - return true; - } - - case KVI_DCC_THREAD_EVENT_MESSAGE: - { - KviCString * str = ((KviThreadDataEvent *)e)->getData(); - outputNoFmt(KVI_OUT_DCCMSG,__tr_no_xgettext_ctx(str->ptr(),"dcc")); - delete str; - return true; - } - break; - case KVI_DCC_THREAD_EVENT_ACTION: - { - int * act = ((KviThreadDataEvent *)e)->getData(); - switch(*act) - { - case KVI_DCC_VIDEO_THREAD_ACTION_START_RECORDING: -// m_pRecordingLabel->setEnabled(true); - break; - case KVI_DCC_VIDEO_THREAD_ACTION_STOP_RECORDING: -// m_pRecordingLabel->setEnabled(false); - break; - case KVI_DCC_VIDEO_THREAD_ACTION_START_PLAYING: -// m_pPlayingLabel->setEnabled(true); - break; - case KVI_DCC_VIDEO_THREAD_ACTION_STOP_PLAYING: -// m_pPlayingLabel->setEnabled(false); - break; - } - delete act; - return true; - } - break; - default: - qDebug("Invalid event type %d received",((KviThreadEvent *)e)->id()); - break; - } - - } - - return KviWindow::event(e); -} - -void KviDccVideo::handleMarshalError(KviError::Code eError) -{ - QString ssss = KviError::getDescription(eError); - output(KVI_OUT_DCCERROR,__tr2qs_ctx("DCC Failed: %Q","dcc"),&ssss); -} - -void KviDccVideo::connected() -{ - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Connected to %Q:%Q","dcc"), - &(m_pMarshal->remoteIp()),&(m_pMarshal->remotePort())); - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Local end is %Q:%Q","dcc"), - &(m_pMarshal->localIp()),&(m_pMarshal->localPort())); - if(!(m_pDescriptor->bActive)) - { - m_pDescriptor->szIp = m_pMarshal->remoteIp(); - m_pDescriptor->szPort = m_pMarshal->remotePort(); - m_pDescriptor->szHost = m_pMarshal->remoteIp(); - } - updateCaption(); - - KviDccVideoThreadOptions * opt = new KviDccVideoThreadOptions; - - opt->pCodec = kvi_dcc_video_get_codec(m_pDescriptor->szCodec.ptr()); - - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Actual codec used is '%s'","dcc"),opt->pCodec->name()); - - m_pSlaveThread = new KviDccVideoThread(this,m_pMarshal->releaseSocket(),opt); - -#ifndef COMPILE_DISABLE_DCC_VIDEO - if(g_pVideoDevicePool) - { - g_pVideoDevicePool->fillDeviceQComboBox(m_pCDevices); - g_pVideoDevicePool->fillInputQComboBox(m_pCInputs); - g_pVideoDevicePool->fillStandardQComboBox(m_pCStandards); - - connect(g_pVideoDevicePool, SIGNAL(deviceRegistered(const QString &) ), SLOT(deviceRegistered(const QString &)) ); - connect(g_pVideoDevicePool, SIGNAL(deviceUnregistered(const QString &) ), SLOT(deviceUnregistered(const QString &)) ); - } -#endif - - m_pSlaveThread->start(); -} - -void KviDccVideo::stopTalking() -{ - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); - e->setData(new int(0)); - m_pSlaveThread->enqueueEvent(e); -} - -void KviDccVideo::startTalking() -{ - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); - e->setData(new int(1)); - m_pSlaveThread->enqueueEvent(e); -} - -void KviDccVideo::startOrStopTalking(bool bStart) -{ - if(bStart)startTalking(); - else stopTalking(); -} - -void KviDccVideo::slotUpdateImage() -{ -#ifndef COMPILE_DISABLE_DCC_VIDEO - if(m_pSlaveThread && isVisible()) - { - m_pOutVideoLabel->setPixmap(QPixmap::fromImage(m_pSlaveThread->m_outImage)); - m_pInVideoLabel->setPixmap(QPixmap::fromImage(m_pSlaveThread->m_inImage)); - } -#endif -} - -void KviDccVideo::deviceRegistered(const QString &) -{ - -#ifndef COMPILE_DISABLE_DCC_VIDEO - g_pVideoDevicePool->fillDeviceQComboBox(m_pCDevices); - g_pVideoDevicePool->fillInputQComboBox(m_pCInputs); - g_pVideoDevicePool->fillStandardQComboBox(m_pCStandards); - - // update the mVideoImageLabel to show the camera frames - g_pVideoDevicePool->open(); - g_pVideoDevicePool->setSize(320, 240); - g_pVideoDevicePool->startCapturing(); - -// setVideoInputParameters(); - -// if ( g_pVideoDevicePool->hasDevices() ) -// { -// m_Timer.start(200); //5fps -// } -#endif -} - - -void KviDccVideo::deviceUnregistered(const QString & ) -{ -#ifndef COMPILE_DISABLE_DCC_VIDEO - g_pVideoDevicePool->fillDeviceQComboBox(m_pCDevices); - g_pVideoDevicePool->fillInputQComboBox(m_pCInputs); - g_pVideoDevicePool->fillStandardQComboBox(m_pCStandards); -#endif -} - -void KviDccVideo::videoInputChanged(int ) -{ - if(m_pSlaveThread) - m_pSlaveThread->restartRecording(m_pCDevices->currentIndex(), m_pCInputs->currentIndex(), m_pCStandards->currentIndex()); -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_video.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/dcc/video.h b/src/modules/dcc/video.h deleted file mode 100644 index 5f09d8fc1..000000000 --- a/src/modules/dcc/video.h +++ /dev/null @@ -1,158 +0,0 @@ -#ifndef _VIDEO_H_ -#define _VIDEO_H_ -//============================================================================= -// -// File : video.h -// Creation date : Tue Nov 10 18:08:09 2009 GMT by Fabio Bas -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2009 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "codec.h" -#include "descriptor.h" -#include "thread.h" -#include "window.h" - -#include "KviWindow.h" -#include "KviDataBuffer.h" -#include "kvi_sockettype.h" -#include "KviTalHBox.h" -#include "KviThemedLabel.h" -#include "KviError.h" - -#include -#include -#include -#include -#include -#include -#include - -#ifndef COMPILE_DISABLE_DCC_VIDEO - #include "avdevice/videodevicepool.h" -#endif - -#ifdef COMPILE_CRYPT_SUPPORT - class KviCryptSessionInfo; -#endif - -class QSlider; -class KviDccMarshal; - -#ifndef _DCC_VIDEO_CPP_ - extern bool kvi_dcc_video_is_valid_codec(const char * codecName); -#endif - -#define KVI_DCC_VIDEO_THREAD_ACTION_START_RECORDING 0 -#define KVI_DCC_VIDEO_THREAD_ACTION_STOP_RECORDING 1 -#define KVI_DCC_VIDEO_THREAD_ACTION_START_PLAYING 2 -#define KVI_DCC_VIDEO_THREAD_ACTION_STOP_PLAYING 3 - -typedef struct _KviDccVideoThreadOptions -{ - QString szVideoDevice; - KviDccVideoCodec * pCodec; -} KviDccVideoThreadOptions; - -class KviDccVideoThread : public KviDccThread -{ - friend class KviDccVideo; -public: - KviDccVideoThread(KviWindow * wnd,kvi_socket_t fd,KviDccVideoThreadOptions * opt); - ~KviDccVideoThread(); -protected: - KviDccVideoThreadOptions * m_pOpt; - KviDataBuffer m_outFrameBuffer; - KviDataBuffer m_inFrameBuffer; - KviDataBuffer m_videoInSignalBuffer; - KviDataBuffer m_textInSignalBuffer; - KviDataBuffer m_videoOutSignalBuffer; - KviDataBuffer m_textOutSignalBuffer; - bool m_bPlaying; - bool m_bRecording; -protected: - QImage m_inImage; - QImage m_outImage; -protected: - bool readWriteStep(); - bool videoStep(); - bool textStep(); - void startRecording(); - void restartRecording(int iDevice, int iInput, int iStandard); - void stopRecording(); - void startPlaying(); - void stopPlaying(); - inline bool isPlaying() { return m_bPlaying; }; - virtual void run(); - virtual bool handleIncomingData(KviDccThreadIncomingData *data,bool bCritical); -}; - - -class KviDccVideo : public KviDccWindow -{ - Q_OBJECT - friend class KviDccVideoThread; -public: - KviDccVideo(KviMainWindow *pFrm,KviDccDescriptor * dcc,const char * name); - ~KviDccVideo(); -protected: - KviThemedLabel * m_pLabel; - KviTalHBox * m_pButtonBox; - KviTalHBox * m_pButtonContainer; - - QLabel * m_pInVideoLabel; - QLabel * m_pOutVideoLabel; - QComboBox * m_pCDevices; - QComboBox * m_pCInputs; - QComboBox * m_pCStandards; - QGridLayout * m_pLayout; - QTimer m_Timer; - QLabel * m_pVideoLabel[2]; - QString * m_pszTarget; - KviDccVideoThread * m_pSlaveThread; - QByteArray m_tmpTextDataOut; - QString m_szLocalNick; -protected: - virtual void triggerCreationEvents(); - virtual void triggerDestructionEvents(); - virtual const QString & target(); - virtual void fillCaptionBuffers(); - virtual QPixmap * myIconPtr(); - virtual bool event(QEvent *e); - virtual void getBaseLogFileName(QString &buffer); - void startTalking(); - void stopTalking(); - void startConnection(); - virtual const QString & localNick(); - virtual void ownMessage(const QString &text, bool bUserFeedback = true); - virtual void ownAction(const QString &text); -protected slots: - void handleMarshalError(KviError::Code eError); - void connected(); - void startOrStopTalking(bool bStart); - void connectionInProgress(); - void slotUpdateImage(); - void deviceRegistered(const QString &); - void deviceUnregistered(const QString &); - void textViewRightClicked(); - void videoInputChanged(int ); -}; - - -#endif //_VOICE_H_ diff --git a/src/modules/dcc/voice.cpp b/src/modules/dcc/voice.cpp deleted file mode 100644 index d78cdfa0a..000000000 --- a/src/modules/dcc/voice.cpp +++ /dev/null @@ -1,1033 +0,0 @@ -//============================================================================= -// -// File : voice.cpp -// Creation date : Thu Aug 23 04:08:09 2001 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "voice.h" -#include "marshal.h" -#include "broker.h" -#include "adpcmcodec.h" -#include "gsmcodec.h" - -#include "kvi_settings.h" -#include "KviIconManager.h" -#include "KviIrcView.h" -#include "KviLocale.h" -#include "kvi_out.h" -#include "KviNetUtils.h" -#include "KviOptions.h" -#include "KviConsoleWindow.h" -#include "KviMemory.h" -#include "kvi_socket.h" -#include "KviIrcConnection.h" -#include "KviTalVBox.h" - -#include -#include -#include - -#if !defined(COMPILE_ON_WINDOWS) && !defined(COMPILE_ON_MINGW) - #include - #include - #include - #include - #include - //#include "KviError.h" - #include // for open() - #include // for ioctl() -#endif - -extern KviDccBroker * g_pDccBroker; - -//Check for the *SS Api....we don't want to fail here... - -#ifndef COMPILE_DISABLE_DCC_VOICE - #ifdef HAVE_LINUX_SOUNDCARD_H - #include - #else - #ifdef HAVE_SYS_SOUNDCARD_H - #include - #else - #ifdef HAVE_SOUNDCARD_H - #include - #else - //CAN NOT COMPILE :( - #define COMPILE_DISABLE_DCC_VOICE - #if !defined(COMPILE_ON_WINDOWS) && !defined(COMPILE_ON_MINGW) - #warning "Cannot find the soundcard.h header; you will NOT be able to use DCC Voice" - #endif - #endif - #endif - #endif -#endif - - -//#define KVI_AUDIO_DEVICE "/dev/dsp" -// 32 fragments, 512 bytes -#define KVI_SNDCTL_FRAG_SIZE 0x00B00009 -#define KVI_FRAGMENT_SIZE_IN_BYTES 512 -#define KVI_FORMAT AFMT_S16_LE -#define KVI_NUM_CHANNELS 1 - - -bool kvi_dcc_voice_is_valid_codec(const char * codecName) -{ -#ifdef COMPILE_USE_GSM - if(kvi_strEqualCI("gsm",codecName)) - { - return kvi_gsm_codec_init(); - } -#endif - if(kvi_strEqualCI("adpcm",codecName))return true; - if(kvi_strEqualCI("null",codecName))return true; - return false; -} - -static KviDccVoiceCodec * kvi_dcc_voice_get_codec(const char * codecName) -{ -#ifdef COMPILE_USE_GSM - if(kvi_strEqualCI("gsm",codecName)) - { - if(kvi_gsm_codec_init())return new KviDccVoiceGsmCodec(); - } -#endif - if(kvi_strEqualCI("adpcm",codecName))return new KviDccVoiceAdpcmCodec(); - if(kvi_strEqualCI("null",codecName))return new KviDccVoiceNullCodec(); - return new KviDccVoiceAdpcmCodec(); -} - - -KviDccVoiceThread::KviDccVoiceThread(KviWindow * wnd,kvi_socket_t fd,KviDccVoiceThreadOptions * opt) -: KviDccThread(wnd,fd) -{ -#ifndef COMPILE_DISABLE_DCC_VOICE - m_pOpt = opt; - m_bPlaying = false; - m_bRecording = false; - m_bSoundcardChecked = false; - m_soundFd = -1; - m_soundFdMode = 0; - m_pInfoMutex = new KviMutex(); - m_bRecordingRequestPending = false; -#endif -} - -KviDccVoiceThread::~KviDccVoiceThread() -{ -#ifndef COMPILE_DISABLE_DCC_VOICE - delete m_pOpt->pCodec; - delete m_pOpt; - delete m_pInfoMutex; -#endif -} - -bool KviDccVoiceThread::checkSoundcard() -{ -#ifdef COMPILE_DISABLE_DCC_VOICE - return false; -#else - bool bOpened = false; - if(m_soundFd == -1) - { - if(!openSoundcard(O_RDONLY))return false; - bOpened = true; - } - - int caps; - - m_bSoundcardChecked = true; - - if(ioctl(m_soundFd,SNDCTL_DSP_GETCAPS,&caps) < 0) - { - postMessageEvent(__tr2qs_ctx("WARNING: failed to check the soundcard duplex capabilities: if this is a half-duplex soundcard, use the DCC VOICE option to force half-duplex algorithm","dcc").toUtf8().data()); - if(bOpened)closeSoundcard(); - return false; - } - - if(!(caps & DSP_CAP_DUPLEX)) - { - m_pOpt->bForceHalfDuplex = true; // the device is half duplex...use it in that way - postMessageEvent(__tr2qs_ctx("Half duplex soundcard detected, you will not be able to talk and listen at the same time","dcc").toUtf8().data()); - } - - if(bOpened)closeSoundcard(); - - return true; -#endif -} - - -bool KviDccVoiceThread::openSoundcard(int mode) -{ -#ifdef COMPILE_DISABLE_DCC_VOICE - return false; -#else - int speed = m_pOpt->iSampleRate; - static int chans=KVI_NUM_CHANNELS; - static int fmt=KVI_FORMAT; - static int frag = KVI_SNDCTL_FRAG_SIZE; - - - if(m_soundFd != -1) - { - if(m_soundFdMode == mode)return true; // already open - closeSoundcard(); - } - - m_soundFd = ::open(m_pOpt->szSoundDevice.ptr(),mode | O_NONBLOCK); - if(m_soundFd < 0)return false; - - if(!m_pOpt->bForceHalfDuplex) - { - if(ioctl(m_soundFd,SNDCTL_DSP_SETDUPLEX,0) < 0)goto exit_false; - } - - if(ioctl(m_soundFd,SNDCTL_DSP_SETFRAGMENT,&frag)<0)goto exit_false; - if(ioctl(m_soundFd,SNDCTL_DSP_SETFMT,&fmt)<0)goto exit_false; - if(ioctl(m_soundFd,SNDCTL_DSP_CHANNELS,&chans)<0)goto exit_false; - if(ioctl(m_soundFd,SNDCTL_DSP_SPEED,&speed)<0)goto exit_false; - if(speed != m_pOpt->iSampleRate) - { - KviCString tmp(KviCString::Format,__tr2qs_ctx("WARNING: failed to set the requested sample rate (%d): the device used closest match (%d)","dcc").toUtf8().data(), - m_pOpt->iSampleRate,speed); - postMessageEvent(tmp.ptr()); - } - - // TODO: #warning "We could also support blocking operations mode" - - m_soundFdMode = mode; - - - return true; - -exit_false: - closeSoundcard(); - return false; -#endif -} - -bool KviDccVoiceThread::openSoundcardForWriting() -{ -#ifndef COMPILE_DISABLE_DCC_VOICE - return openSoundcardWithDuplexOption(O_WRONLY,O_RDONLY); -#else - return false; -#endif -} - -bool KviDccVoiceThread::openSoundcardForReading() -{ -#ifndef COMPILE_DISABLE_DCC_VOICE - return openSoundcardWithDuplexOption(O_RDONLY,O_WRONLY); -#else - return false; -#endif -} - -bool KviDccVoiceThread::openSoundcardWithDuplexOption(int openMode,int failMode) -{ -#ifndef COMPILE_DISABLE_DCC_VOICE - if(m_soundFd == -1) - { - // soundcard not open yet...open for write (at least) - if(m_pOpt->bForceHalfDuplex) - { - // Forcing half duplex... (user option or the card does not support full duplex mode) - if(!openSoundcard(openMode))return false; - } else { - // Try read/write open - if(!openSoundcard(O_RDWR)) - { - // half-duplex sound card ? - if(!m_bSoundcardChecked) - { - // We haven't checked the full-duplex support yet... - // Try to open in RDONLY o WRONLY mode - if(!openSoundcard(openMode))return false; - if(!checkSoundcard()) - { - postMessageEvent(__tr2qs_ctx("Ops...failed to test the soundcard capabilities...expect problems...","dcc").toUtf8().data()); - } - } // else the test has been done and it is a full duplex card that is just busy - } - } - } else { - // Hmmm...already open - // If it is open in O_RDWR or O_WRONLY mode...it is ok for us - // but if it is open in O_RDONLY mode...we can do nothing...just wait - return (m_soundFdMode != failMode); - } - - return true; -#else - return false; -#endif -} - -void KviDccVoiceThread::closeSoundcard() -{ -#ifndef COMPILE_DISABLE_DCC_VOICE - if(m_soundFd != -1) - { - ::close(m_soundFd); - m_soundFd = -1; - m_soundFdMode = 0; - } -#endif -} - -bool KviDccVoiceThread::readWriteStep() -{ -#ifndef COMPILE_DISABLE_DCC_VOICE - // Socket management - bool bCanRead; - bool bCanWrite; - - if(kvi_select(m_fd,&bCanRead,&bCanWrite)) - { - if(bCanRead) - { - unsigned int actualSize = m_inFrameBuffer.size(); - m_inFrameBuffer.resize(actualSize + 1024); - int readLen = kvi_socket_recv(m_fd,(void *)(m_inFrameBuffer.data() + actualSize),1024); - if(readLen > 0) - { - if(readLen < 1024)m_inFrameBuffer.resize(actualSize + readLen); - m_pOpt->pCodec->decode(&m_inFrameBuffer,&m_inSignalBuffer); -//#warning "A maximum length for the signal buffer is actually needed!!!" - } else { - if(!handleInvalidSocketRead(readLen))return false; - m_inFrameBuffer.resize(actualSize); - } - }// else { - // m_uSleepTime += 100; - //} - - if(bCanWrite) - { - // Have somethihg to write ? - if(m_outFrameBuffer.size() > 0) - { - int written = kvi_socket_send(m_fd,m_outFrameBuffer.data(),m_outFrameBuffer.size()); - if(written > 0) - { - m_outFrameBuffer.remove(written); - } else { - if(!handleInvalidSocketRead(written))return false; - } - }// else { - // m_uSleepTime += 100; - // } - }// else { - // m_uSleepTime += 100; -// } -//#warning "Usleep here ?" - }// else { -// if(!(m_bPlaying || m_bRecording)) -// { -// // Really NOTHING is happening...sleep a bit more -// m_uSleepTime += 800; -// } else { -// m_uSleepTime += 100; -// } -// } - -#endif // !COMPILE_DISABLE_DCC_VOICE - return true; -} - -bool KviDccVoiceThread::soundStep() -{ -#ifndef COMPILE_DISABLE_DCC_VOICE - // Are we playing ? - if(m_bPlaying) - { - // Do we have something to write ? - audio_buf_info info; - if(m_inSignalBuffer.size() > 0) - { - // Get the number of fragments that can be written to the soundcard without blocking - - if(ioctl(m_soundFd,SNDCTL_DSP_GETOSPACE,&info) < 0) - { - qDebug("get o space failed"); - info.bytes = KVI_FRAGMENT_SIZE_IN_BYTES; // dummy... if this is not correct...well...we will block for 1024/16000 of a sec - info.fragments = 1; - info.fragsize = KVI_FRAGMENT_SIZE_IN_BYTES; - } - if(info.fragments > 0) - { - int toWrite = info.fragments * info.fragsize; - //qDebug("Can write %d bytes",toWrite); - if(m_inSignalBuffer.size() < toWrite)toWrite = m_inSignalBuffer.size(); - int written = write(m_soundFd,m_inSignalBuffer.data(),toWrite); - if(written > 0)m_inSignalBuffer.remove(written); - else { -//#warning "Do something for -1 here ?" -//#warning "Usleep ?" - } - } //else { - // No stuff can be written...we are running too fast ? - // m_uSleepTime += 100; // sleep for a while - //} - } else { - // hmmmm....playing, but nothing to write, possible underrun or EOF - // a nice idea would be to use SNDCTL_DSP_GETODELAY here... - // but it appears to be broken on some audio devices - if(ioctl(m_soundFd,SNDCTL_DSP_GETOSPACE,&info) < 0)info.fragstotal = info.fragments; // dummy...but what should we do ? - if(info.fragstotal == info.fragments) - { - // underrun or EOF: close the device - stopPlaying(); - } - } - } else { - // do we have anything to play ? - if(m_inSignalBuffer.size() > 0) - { - if(m_inSignalBuffer.size() >= m_pOpt->iPreBufferSize) - { - // yep...stuff to play... open the soundcard, if possible - startPlaying(); - - m_iLastSignalBufferSize = m_inSignalBuffer.size(); - } else { - // have stuff to play, but it's not enough to fill the pre-buffer - // - struct timeval tv; - gettimeofday(&tv,0); - - long int sigBufferTime = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); - - if(m_inSignalBuffer.size() == m_iLastSignalBufferSize) - { - // the same signal buffer size... check the time - // m_pOpt->iPreBufferSize / 16 gives us the preBufferTime in msecs - // we calc the remaining preBufferTime by subtracting the - // size of buffer already filled and we also add 50 milliseconds... smart heuristic - int preBufferTime = ((m_pOpt->iPreBufferSize - m_iLastSignalBufferSize) / 16) + 50; - // if the buffer size hasn't changed since preBufferTime - // it's time to start playing anyway, since there is - // either a network stall or it was just a really short data stream - if((sigBufferTime - m_iLastSignalBufferTime) > preBufferTime) - { - startPlaying(); - if(m_bPlaying)m_iLastSignalBufferSize = 0; - } - } else { - // signal buffer size differs...we have received new packets - // and still pre-buffering - m_iLastSignalBufferSize = m_inSignalBuffer.size(); - m_iLastSignalBufferTime = sigBufferTime; - } - } - - } - } - - // Are we recording ? - if(m_bRecording) - { - fd_set rs; - FD_ZERO(&rs); - FD_SET(m_soundFd,&rs); - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 10; - int ret = select(m_soundFd + 1,&rs,0,0,&tv); - if(ret > 0) - { - // This is rather easy... - audio_buf_info info; - if(ioctl(m_soundFd,SNDCTL_DSP_GETISPACE,&info) < 0) - { - qDebug("Ispace failed"); - info.fragments = 0; // dummy... - info.bytes = 0; - } - - //qDebug("INFO: fragments: %d, fragstotal: %d, fragsize: %d, bytes: %d",info.fragments,info.fragstotal,info.fragsize,info.bytes); - - if(info.fragments == 0 && info.bytes == 0) - { - // force a dummy read: the device needs to be triggered - info.fragments = 1; - } - - if(info.fragments > 0) - { - int oldSize = m_outSignalBuffer.size(); - int available = info.fragments * info.fragsize; - m_outSignalBuffer.addSize(available); - int readed = read(m_soundFd,m_outSignalBuffer.data() + oldSize,available); - - if(readed < available) - { - // huh ? ...error ? - if(readed >= 0)m_outSignalBuffer.resize(oldSize + readed); - else { - if((errno == EINTR) || (errno == EAGAIN)) - { - m_outSignalBuffer.resize(oldSize); - } else { -//#warning "Critical error...do something reasonable!" - m_outSignalBuffer.resize(oldSize); - } - } - } -/* - qDebug("Signal buffer:"); - for(int i=0;i<200;i+=2) - { - if(i >= m_outSignalBuffer.size())break; - printf("%04x ",*(((unsigned short *)(m_outSignalBuffer.data() + i)))); - if((i % 6) == 0)printf("\n"); - } - qDebug("END\n"); -*/ - m_pOpt->pCodec->encode(&m_outSignalBuffer,&m_outFrameBuffer); - } - }// else { - // Nothing to read - // m_uSleepTime += 100; - // } - } - -#endif // !COMPILE_DISABLE_DCC_VOICE - return true; -} - -void KviDccVoiceThread::startRecording() -{ -#ifndef COMPILE_DISABLE_DCC_VOICE - //qDebug("Start recording"); - if(m_bRecording)return; // already started - if(openSoundcardForReading()) - { -// qDebug("Posting event"); - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); - e->setData(new int(KVI_DCC_VOICE_THREAD_ACTION_START_RECORDING)); - postEvent(parent(),e); - - m_bRecording = true; - m_bRecordingRequestPending = false; - } else { - m_bRecordingRequestPending = true; - } -#endif -} - -void KviDccVoiceThread::stopRecording() -{ -#ifndef COMPILE_DISABLE_DCC_VOICE - //qDebug("Stop recording"); - m_bRecordingRequestPending = false; - if(!m_bRecording)return; // already stopped - - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); - e->setData(new int(KVI_DCC_VOICE_THREAD_ACTION_STOP_RECORDING)); - postEvent(parent(),e); - - m_bRecording = false; - if(!m_bPlaying)closeSoundcard(); -#endif -} - -void KviDccVoiceThread::startPlaying() -{ -#ifndef COMPILE_DISABLE_DCC_VOICE - //qDebug("Start playing"); - if(m_bPlaying)return; - - if(openSoundcardForWriting()) - { - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); - e->setData(new int(KVI_DCC_VOICE_THREAD_ACTION_START_PLAYING)); - postEvent(parent(),e); - m_bPlaying = true; - } -#endif -} - -void KviDccVoiceThread::stopPlaying() -{ -#ifndef COMPILE_DISABLE_DCC_VOICE - //qDebug("Stop playing"); - if(!m_bPlaying)return; - - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); - e->setData(new int(KVI_DCC_VOICE_THREAD_ACTION_STOP_PLAYING)); - postEvent(parent(),e); - - m_bPlaying = false; - if(!m_bRecording)closeSoundcard(); -#endif -} - -void KviDccVoiceThread::run() -{ -#ifndef COMPILE_DISABLE_DCC_VOICE - for(;;) - { -// m_uSleepTime = 0; - - // Dequeue events - while(KviThreadEvent * e = dequeueEvent()) - { - if(e->id() == KVI_THREAD_EVENT_TERMINATE) - { - delete e; - goto exit_dcc; - } else if(e->id() == KVI_DCC_THREAD_EVENT_ACTION) - { - int * act = ((KviThreadDataEvent *)e)->getData(); - if(*act)startRecording(); - else stopRecording(); - delete act; - delete e; - } else { - // Other events are senseless to us - delete e; - } - } - - if(!readWriteStep())goto exit_dcc; - if(!soundStep())goto exit_dcc; - - m_pInfoMutex->lock(); - m_iInputBufferSize = m_inSignalBuffer.size(); - m_iOutputBufferSize = (m_outFrameBuffer.size() / m_pOpt->pCodec->encodedFrameSize()) * m_pOpt->pCodec->decodedFrameSize(); - m_pInfoMutex->unlock(); - - // Actually the maximum that we can sleep here is - // around 500 usecs... = 0.0005 sec -> 8 bytes at 8 KHz - - // if(m_uSleepTime)usleep(m_uSleepTime); - - // Start recording if the request was not fulfilled yet - if(m_bRecordingRequestPending)startRecording(); - } - - -exit_dcc: - -#endif //! COMPILE_DISABLE_DCC_VOICE - closeSoundcard(); - kvi_socket_close(m_fd); - m_fd = KVI_INVALID_SOCKET; -} - - -KviDccVoice::KviDccVoice(KviMainWindow *pFrm,KviDccDescriptor * dcc,const char * name) -: KviDccWindow(KVI_WINDOW_TYPE_DCCVOICE,pFrm,name,dcc) -{ - m_pDescriptor = dcc; - m_pSlaveThread = 0; - - m_pSplitter = new KviTalSplitter(Qt::Horizontal,this); - m_pSplitter->setObjectName("dcc_window_splitter"); - m_pIrcView = new KviIrcView(m_pSplitter,pFrm,this); - - m_pHBox = new KviTalHBox(this); - - KviTalVBox * vbox = new KviTalVBox(m_pHBox); - - m_pInputLabel = new QLabel(__tr2qs_ctx("Input buffer","dcc"),vbox); - m_pInputLabel->setFrameStyle(QFrame::Sunken | QFrame::Panel); - m_pOutputLabel = new QLabel(__tr2qs_ctx("Output buffer","dcc"),vbox); - m_pOutputLabel->setFrameStyle(QFrame::Sunken | QFrame::Panel); - vbox->setSpacing(1); - - KviTalVBox * vbox2 = new KviTalVBox(m_pHBox); - - m_pRecordingLabel = new QLabel(vbox2); - m_pRecordingLabel->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_RECORD))); - m_pRecordingLabel->setEnabled(false); - m_pRecordingLabel->setFrameStyle(QFrame::Raised | QFrame::Panel); - - m_pPlayingLabel = new QLabel(vbox2); - m_pPlayingLabel->setPixmap(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_PLAY))); - m_pPlayingLabel->setEnabled(false); - m_pPlayingLabel->setFrameStyle(QFrame::Raised | QFrame::Panel); - - vbox2->setSpacing(1); - - //#warning "The volume slider should be enabled only when receiving data" - //m_pVolumeSlider = new QSlider(-100, 0, 10, 0, Qt::Vertical, m_pHBox, "dcc_voice_volume_slider"); - m_pVolumeSlider = new QSlider(Qt::Vertical,m_pHBox); - m_pVolumeSlider->setObjectName("dcc_voice_volume_slider"); - m_pVolumeSlider->setMinimum(-100); - m_pVolumeSlider->setMaximum(0); - m_pVolumeSlider->setPageStep(10); - m_pVolumeSlider->setValue(0); - - m_pVolumeSlider->setValue(getMixerVolume()); - /* Update the tooltip */ - setMixerVolume(m_pVolumeSlider->value()); - m_pVolumeSlider->setMaximumWidth(16); - m_pVolumeSlider->setMaximumHeight(2*m_pPlayingLabel->height()); - connect(m_pVolumeSlider, SIGNAL(valueChanged(int)), this, SLOT(setMixerVolume(int))); - - m_pTalkButton = new QToolButton(m_pHBox); - m_pTalkButton->setEnabled(false); - m_pTalkButton->setCheckable(true); - QIcon iset; - iset.addPixmap(*(g_pIconManager->getBigIcon(KVI_BIGICON_DISCONNECTED)),QIcon::Normal,QIcon::Off); - iset.addPixmap(*(g_pIconManager->getBigIcon(KVI_BIGICON_CONNECTED)),QIcon::Normal,QIcon::On); - m_pTalkButton->setIcon(iset); - m_pTalkButton->setIconSize(QSize(32,32)); - connect(m_pTalkButton,SIGNAL(toggled(bool)),this,SLOT(startOrStopTalking(bool))); - - m_pHBox->setStretchFactor(vbox,1); - m_pHBox->setMargin(2); - m_pHBox->setSpacing(1); - - //setFocusHandler(m_pIrcView,this); - - m_pMarshal = new KviDccMarshal(this); - connect(m_pMarshal,SIGNAL(error(int)),this,SLOT(handleMarshalError(int))); - connect(m_pMarshal,SIGNAL(connected()),this,SLOT(connected())); - connect(m_pMarshal,SIGNAL(inProgress()),this,SLOT(connectionInProgress())); - - m_pUpdateTimer = new QTimer(); - - startConnection(); -} - -KviDccVoice::~KviDccVoice() -{ - g_pDccBroker->unregisterDccWindow(this); - if(m_pSlaveThread) - { - m_pSlaveThread->terminate(); - delete m_pSlaveThread; - m_pSlaveThread = 0; - } - - KviThreadManager::killPendingEvents(this); - - delete m_pUpdateTimer; -// delete m_pDescriptor; -// delete m_pMarshal; -} - - -void KviDccVoice::startConnection() -{ - if(!(m_pDescriptor->bActive)) - { - // PASSIVE CONNECTION - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Attempting a passive DCC VOICE connection","dcc")); - KviError::Code eError = m_pMarshal->dccListen(m_pDescriptor->szListenIp,m_pDescriptor->szListenPort,m_pDescriptor->bDoTimeout); - if(eError != KviError::Success) - handleMarshalError(eError); - } else { - // ACTIVE CONNECTION - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Attempting an active DCC VOICE connection","dcc")); - KviError::Code eError = m_pMarshal->dccConnect(m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data(),m_pDescriptor->bDoTimeout); - if(eError != KviError::Success) - handleMarshalError(eError); - } -} - -void KviDccVoice::connectionInProgress() -{ - if(m_pDescriptor->bActive) - { - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Contacting host %Q on port %Q","dcc"),&(m_pDescriptor->szIp),&(m_pDescriptor->szPort)); - } else { - - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Listening on interface %Q port %Q","dcc"), - &(m_pMarshal->localIp()),&(m_pMarshal->localPort())); - - if(m_pDescriptor->bSendRequest) - { - QString ip = !m_pDescriptor->szFakeIp.isEmpty() ? m_pDescriptor->szFakeIp : m_pDescriptor->szListenIp; - KviCString port = !m_pDescriptor->szFakePort.isEmpty() ? m_pDescriptor->szFakePort : m_pMarshal->localPort(); -//#warning "OPTION FOR SENDING 127.0.0.1 and so on (not an unsigned nuumber)" - struct in_addr a; - if(KviNetUtils::stringIpToBinaryIp(ip,&a)) { - ip.setNum(htonl(a.s_addr)); - } - - m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC VOICE %s %Q %s %d%c", - m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(), - 0x01,m_pDescriptor->szCodec.ptr(), - &ip,port.ptr(),m_pDescriptor->iSampleRate,0x01); - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Sent DCC VOICE (%s) request to %Q, waiting for the remote client to connect...","dcc"), - m_pDescriptor->szCodec.ptr(),&(m_pDescriptor->szNick)); - } else output(KVI_OUT_DCCMSG,__tr2qs_ctx("DCC VOICE request not sent: awaiting manual connections","dcc")); - } -} - -const QString & KviDccVoice::target() -{ - // This may change on the fly... - m_szTarget.sprintf("%s@%s:%s", - m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data()); - return m_szTarget; -} - -void KviDccVoice::getBaseLogFileName(QString &buffer) -{ - buffer.sprintf("dccvoice_%s_%s_%s",m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szLocalFileName.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data()); -} - -void KviDccVoice::fillCaptionBuffers() -{ - KviCString tmp(KviCString::Format,"DCC Voice %s@%s:%s %s", - m_pDescriptor->szNick.toUtf8().data(),m_pDescriptor->szIp.toUtf8().data(),m_pDescriptor->szPort.toUtf8().data(), - m_pDescriptor->szLocalFileName.toUtf8().data()); - - m_szPlainTextCaption = tmp; -} - -QPixmap * KviDccVoice::myIconPtr() -{ - return g_pIconManager->getSmallIcon(KVI_SMALLICON_DCCVOICE); -} - -bool KviDccVoice::event(QEvent *e) -{ - if(e->type() == KVI_THREAD_EVENT) - { - switch(((KviThreadEvent *)e)->id()) - { - case KVI_DCC_THREAD_EVENT_ERROR: - { - KviError::Code * pError = ((KviThreadDataEvent *)e)->getData(); - QString ssss = KviError::getDescription(*pError); - output(KVI_OUT_DCCERROR,__tr2qs_ctx("ERROR: %Q","dcc"),&(ssss)); - delete pError; - m_pUpdateTimer->stop(); - updateInfo(); - m_pTalkButton->setEnabled(false); - m_pRecordingLabel->setEnabled(false); - m_pPlayingLabel->setEnabled(false); - return true; - } - break; - case KVI_DCC_THREAD_EVENT_MESSAGE: - { - KviCString * str = ((KviThreadDataEvent *)e)->getData(); - outputNoFmt(KVI_OUT_DCCMSG,__tr_no_xgettext_ctx(str->ptr(),"dcc")); - delete str; - return true; - } - break; - case KVI_DCC_THREAD_EVENT_ACTION: - { - int * act = ((KviThreadDataEvent *)e)->getData(); - switch(*act) - { - case KVI_DCC_VOICE_THREAD_ACTION_START_RECORDING: - m_pRecordingLabel->setEnabled(true); - break; - case KVI_DCC_VOICE_THREAD_ACTION_STOP_RECORDING: - m_pRecordingLabel->setEnabled(false); - break; - case KVI_DCC_VOICE_THREAD_ACTION_START_PLAYING: - m_pPlayingLabel->setEnabled(true); - break; - case KVI_DCC_VOICE_THREAD_ACTION_STOP_PLAYING: - m_pPlayingLabel->setEnabled(false); - break; - } - delete act; - return true; - } - break; - default: - qDebug("Invalid event type %d received",((KviThreadEvent *)e)->id()); - break; - } - - } - - return KviWindow::event(e); -} - -void KviDccVoice::updateInfo() -{ - if(m_pSlaveThread) - { - m_pSlaveThread->m_pInfoMutex->lock(); - int iOSize = m_pSlaveThread->m_iOutputBufferSize; - int iISize = m_pSlaveThread->m_iInputBufferSize; - m_pSlaveThread->m_pInfoMutex->unlock(); - KviCString tmp(KviCString::Format,__tr_ctx("Input buffer: %d bytes","dcc"),iISize); - m_pInputLabel->setText(tmp.ptr()); - tmp.sprintf(__tr_ctx("Output buffer: %d bytes","dcc"),iOSize); - m_pOutputLabel->setText(tmp.ptr()); - } -} - -void KviDccVoice::resizeEvent(QResizeEvent *) -{ - int hght2 = m_pHBox->sizeHint().height(); - m_pHBox->setGeometry(0,0,width(),hght2); - m_pSplitter->setGeometry(0,hght2,width(),height() - hght2); -} - -QSize KviDccVoice::sizeHint() const -{ - int w = m_pIrcView->sizeHint().width(); - int w2 = m_pHBox->sizeHint().width(); - QSize ret(w > w2 ? w : w2, m_pIrcView->sizeHint().height() + m_pHBox->sizeHint().height()); - return ret; -} - -void KviDccVoice::handleMarshalError(KviError::Code eError) -{ - QString ssss = KviError::getDescription(eError); - output(KVI_OUT_DCCERROR,__tr2qs_ctx("DCC Failed: %Q","dcc"),&ssss); - m_pTalkButton->setEnabled(false); - m_pTalkButton->setChecked(false); - m_pRecordingLabel->setEnabled(false); - m_pPlayingLabel->setEnabled(false); -} - -void KviDccVoice::connected() -{ - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Connected to %Q:%Q","dcc"), - &(m_pMarshal->remoteIp()),&(m_pMarshal->remotePort())); - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Local end is %Q:%Q","dcc"), - &(m_pMarshal->localIp()),&(m_pMarshal->localPort())); - if(!(m_pDescriptor->bActive)) - { - m_pDescriptor->szIp = m_pMarshal->remoteIp(); - m_pDescriptor->szPort = m_pMarshal->remotePort(); - m_pDescriptor->szHost = m_pMarshal->remoteIp(); - } - updateCaption(); - - connect(m_pUpdateTimer,SIGNAL(timeout()),this,SLOT(updateInfo())); - m_pUpdateTimer->start(1000); - - KviDccVoiceThreadOptions * opt = new KviDccVoiceThreadOptions; - - - opt->pCodec = kvi_dcc_voice_get_codec(m_pDescriptor->szCodec.ptr()); - - output(KVI_OUT_DCCMSG,__tr2qs_ctx("Actual codec used is '%s'","dcc"),opt->pCodec->name()); - - opt->bForceHalfDuplex = KVI_OPTION_BOOL(KviOption_boolDccVoiceForceHalfDuplex); -// opt->bForceDummyReadTrigger = false; - opt->iPreBufferSize = KVI_OPTION_UINT(KviOption_uintDccVoicePreBufferSize); - opt->szSoundDevice = KVI_OPTION_STRING(KviOption_stringDccVoiceSoundDevice).toUtf8().data(); - opt->iSampleRate = m_pDescriptor->iSampleRate; - - m_pSlaveThread = new KviDccVoiceThread(this,m_pMarshal->releaseSocket(),opt); - connect(m_pUpdateTimer,SIGNAL(timeout()),this,SLOT(updateInfo())); - m_pSlaveThread->start(); - - m_pTalkButton->setEnabled(true); -} - -void KviDccVoice::stopTalking() -{ - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); - e->setData(new int(0)); - m_pSlaveThread->enqueueEvent(e); -} - -void KviDccVoice::startTalking() -{ - KviThreadDataEvent * e = new KviThreadDataEvent(KVI_DCC_THREAD_EVENT_ACTION); - e->setData(new int(1)); - m_pSlaveThread->enqueueEvent(e); -} - -void KviDccVoice::startOrStopTalking(bool bStart) -{ - if(bStart)startTalking(); - else stopTalking(); -} - -int KviDccVoice::getMixerVolume(void) const -{ -#ifndef COMPILE_DISABLE_DCC_VOICE - int fd; - int ret; - int left; //, right; - int req; - - if((fd = ::open(KVI_OPTION_STRING(KviOption_stringDccVoiceMixerDevice).toUtf8().data(), O_RDONLY)) == -1) - { - return 0; - } - - req = KVI_OPTION_BOOL(KviOption_boolDccVoiceVolumeSliderControlsPCM) ? SOUND_MIXER_READ_PCM : SOUND_MIXER_READ_VOLUME; - - if(::ioctl(fd,req,&ret)) - { - ::close(fd); - return 0; - } - - left = (ret & 0x00ff); -// right = (ret & 0xff00) >> 8; - - ::close(fd); - - return -left; -#else - return 0; -#endif -} - -void KviDccVoice::setMixerVolume(int vol) -{ -#ifndef COMPILE_DISABLE_DCC_VOICE - int fd; - int val; - int req; - - if((fd = ::open(KVI_OPTION_STRING(KviOption_stringDccVoiceMixerDevice).toUtf8().data(), O_WRONLY)) == -1) - return; - - req = KVI_OPTION_BOOL(KviOption_boolDccVoiceVolumeSliderControlsPCM) ? SOUND_MIXER_WRITE_PCM : SOUND_MIXER_WRITE_VOLUME; - - val = (-vol << 8) | -vol; - ::ioctl(fd, req, &val); - ::close(fd); - - m_pVolumeSlider->setToolTip(__tr2qs_ctx("Volume: %1","dcc").arg(-vol)); -#endif -} - - -/* The code below doesn't work. Guess I have to catch some other widget's focusInEvent. Which one ? */ -/* The point is to move the volume slider to correct position if for example user switched to - * another KVirc window, fired up xmms, changed the volume, and returned to our dcc voice window */ -void KviDccVoice::focusInEvent(QFocusEvent *e) -{ -// qDebug("focusInEvent()"); - m_pVolumeSlider->setValue(getMixerVolume()); - setMixerVolume(m_pVolumeSlider->value()); - - KviWindow::focusInEvent(e); -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_voice.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/dcc/voice.h b/src/modules/dcc/voice.h deleted file mode 100644 index 5f6ec6bff..000000000 --- a/src/modules/dcc/voice.h +++ /dev/null @@ -1,443 +0,0 @@ -#ifndef _VOICE_H_ -#define _VOICE_H_ -//============================================================================= -// -// File : voice.h -// Creation date : Thu Aug 23 04:08:10 2001 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "codec.h" -#include "descriptor.h" -#include "thread.h" -#include "window.h" - -#include "KviWindow.h" -#include "KviDataBuffer.h" -#include "kvi_sockettype.h" -#include "KviTalHBox.h" -#include "KviError.h" - -#include -#include -#include - -class QSlider; -class KviDccMarshal; - -#ifndef _DCC_VOICE_CPP_ - extern bool kvi_dcc_voice_is_valid_codec(const char * codecName); -#endif - -#define KVI_DCC_VOICE_THREAD_ACTION_START_RECORDING 0 -#define KVI_DCC_VOICE_THREAD_ACTION_STOP_RECORDING 1 -#define KVI_DCC_VOICE_THREAD_ACTION_START_PLAYING 2 -#define KVI_DCC_VOICE_THREAD_ACTION_STOP_PLAYING 3 - -typedef struct _KviDccVoiceThreadOptions -{ - bool bForceHalfDuplex; - int iPreBufferSize; - int iSampleRate; - KviCString szSoundDevice; - KviDccVoiceCodec * pCodec; -} KviDccVoiceThreadOptions; - -class KviDccVoiceThread : public KviDccThread -{ - friend class KviDccVoice; -public: - KviDccVoiceThread(KviWindow * wnd,kvi_socket_t fd,KviDccVoiceThreadOptions * opt); - ~KviDccVoiceThread(); -protected: -// bool m_bUseGsm; - KviDccVoiceThreadOptions * m_pOpt; - int m_soundFd; - int m_soundFdMode; - KviDataBuffer m_outFrameBuffer; - KviDataBuffer m_inFrameBuffer; - KviDataBuffer m_inSignalBuffer; - KviDataBuffer m_outSignalBuffer; - bool m_bPlaying; - bool m_bRecording; - bool m_bRecordingRequestPending; - bool m_bSoundcardChecked; - int m_iLastSignalBufferSize; - long m_iLastSignalBufferTime; -// unsigned int m_uSleepTime; - KviMutex * m_pInfoMutex; - // stuff protected by the mutex: - int m_iInputBufferSize; - int m_iOutputBufferSize; -protected: - bool checkSoundcard(); - bool openSoundcardWithDuplexOption(int openMode,int failMode); - bool openSoundcard(int mode); - bool openSoundcardForWriting(); - bool openSoundcardForReading(); - void closeSoundcard(); - bool readWriteStep(); - bool soundStep(); - void startRecording(); - void stopRecording(); - void startPlaying(); - void stopPlaying(); - virtual void run(); -}; - - -class KviDccVoice : public KviDccWindow -{ - Q_OBJECT -public: - KviDccVoice(KviMainWindow *pFrm,KviDccDescriptor * dcc,const char * name); - ~KviDccVoice(); -protected: - KviTalHBox * m_pHBox; - QSlider * m_pVolumeSlider; - QLabel * m_pInputLabel; - QLabel * m_pOutputLabel; - QLabel * m_pRecordingLabel; - QLabel * m_pPlayingLabel; - QToolButton * m_pTalkButton; - QTimer * m_pUpdateTimer; - QString m_szTarget; - KviDccVoiceThread * m_pSlaveThread; -protected: - virtual void focusInEvent(QFocusEvent *); - virtual const QString & target(); - virtual void fillCaptionBuffers(); - virtual QPixmap * myIconPtr(); - virtual void resizeEvent(QResizeEvent *e); - virtual QSize sizeHint() const; - virtual bool event(QEvent *e); - virtual void getBaseLogFileName(QString &buffer); - void startTalking(); - void stopTalking(); - void startConnection(); - int getMixerVolume(void) const; -protected slots: - void handleMarshalError(KviError::Code eError); - void connected(); - void updateInfo(); - void startOrStopTalking(bool bStart); - void setMixerVolume(int); - void connectionInProgress(); -// void stopTalking(); -}; - -#if 0 - - - -/* - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -CODEC DEFINITION - - Sample rate = samples/sec (ex. 8000) - Sample size = bits (ex. 16 bits) - Sample endianness = le/be - - Sample compressor = name - - ::: - - 8000:16:le:null - 8000:16:le:gsm - 8000:16:le:adpcm - -////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -class KviVoiceParty -{ -public: - KviVoiceParty(const QString &szNick,const QString &szIp,unsigned short uPort); - ~KviVoiceParty(); -protected: - QString m_szIp; - unsigned short m_uPort; - QString m_szNick; - KviPointerList * m_pChildrenTree; -public: - const QString & ip(){ return m_szIp; }; - unsigned short port(){ return m_uPort; }; - const QString & nick(){ return m_szNick; }; - void addChild(KviVoiceParty * pChild); -}; - - -KviVoiceParty::KviVoiceParty(const QString &szNick,const QString &szIp,unsigned short uPort) -: m_szIp(szIp), m_uPort(uPort), m_szNick(szNick) -{ - m_pChildrenTree = 0; -} - -KviVoiceParty::~KviVoiceParty() -{ - if(m_pChildrenTree)delete m_pChildrenTree; -} - -void KviVoiceParty::addChild(KviVoiceParty * pChild) -{ - if(!m_pChildrenTree) - { - m_pChildrenTree = new KviPointerList; - m_pChildrenTree->setAutoDelete(true); - } - m_pChildrenTree->append(pChild); -} - -////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -class KviVoiceAudioEncoder -{ -public: - KviVoiceAudioEncoder(); - ~KviVoiceAudioEncoder(); -public: - -}; - -class KviVoiceAudioDecoder -{ -public: - KviVoiceAudioDecoder(); - ~KviVoiceAudioDecoder(); -}; - -////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -class KviVoiceLink -{ -public: - KviVoiceLink(KviVoiceParty * pRemoteParty); - ~KviVoiceLink(); -protected: - QString m_szId; - KviVoiceParty * m_pRemoteParty; - KviVoiceAudioEncoder * m_pAudioEncoder; - KviVoiceAudioDecoder * m_pAudioDecoder; -public: - const QStirng & id(){ return m_szId; }; - KviVoiceParty * remoteParty(){ return m_pRemoteParty; }; -}; - -KviVoiceLink::KviVoiceLink(KviVoiceParty * pRemoteParty) -{ - KviQString::sprintf("%Q:%u",&(pRemoteParty->nick()),pRemoteParty->port()); - m_pRemoteParty = pRemoteParty; - m_pAudioEncoder = 0; - m_pAudioDecoder = 0; -} - -KviVoiceLink::~KviVoiceLink() -{ - delete m_pRemoteParty; - if(m_pAudioEncoder)delete m_pAudioEncoder; - if(m_pAudioDecoder)delete m_pAudioDecoder; -} - -////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -class KviVoice_r8000s16eL_to_r8000s16eB_Transformer -{ - -} - -class KviVoice_r8000s16eB_to_r8000s16eL_Transformer -{ - -} - -class KviVoice_r11025s16eL_to_r11025s16eB_Transformer -{ - -} - -class KviVoice_r11025s16eB_to_r11025s16eL_Transformer -{ - -} - -class KviVoice_r11025s16eL_to_r8000s16eL_Transformer -{ - -} - -class KviVoice_r11025s16eL_to_r8000s16eB_Transformer -{ - -} - -class KviVoice_r11025s16eB_to_r8000s16eL_Transformer -{ - -} - -class KviVoice_r8000s16eL_to_r11025s16eL_Transformer -{ - -} - -class KviVoice_r8000s16eL_to_r11025s16eB_Transformer -{ - -} - -class KviVoice_r8000s16eB_to_r11025s16eL_Transformer -{ - -} - - - -class KviVoiceConference -{ -public: - KviVoiceConference(); - ~KviVoiceConference(); -public: - KviPointerList * m_pLinks; - KviPointerHashTable * - SOCKET m_hUdpSocket; - QString m_szLastError; - - unsigned int m_uLocalAudioSampleRate; // samples/sec - unsigned int m_uLocalAudioSampleSize; // bits - unsigned int m_uLocalAudioEndianness; // 0 = le, 1 = be - -public: - void conferenceThread(); -protected: - void conferenceThreadMain(); - bool setupUdpSocket(); -}; - -KviVoiceConference::KviVoiceConference() -{ - m_pLinks = new KviPointerList; - m_pLinks->setAutoDelete(true); -} - -KviVoiceConference::~KviVoiceConference() -{ - delete m_pLinks; -} - -bool KviVoiceConference::setupUdpSocket() -{ - return true; -} - -void KviVoiceConference::shutdownUdpSocket() -{ -} - -void KviVoiceConference::conferenceThreadMain() -{ - for(;;) - { - readAndDecompressIncomingDataForEveryLink(); - - mixIncomingDataToASingleStream(); - playIncomingDataSingleStream(); - - readLocalAudioStream(); - - foreach(link) - { - mixLocalAndOtherIncomingDataStreams() - compressAndSendOtherIncomingDataStreams() - } - - } -} - -void KviVoiceConference::conferenceThread() -{ - if(!setupUdpSocket())return; - - conferenceThreadMain(); - - shutdownUdpSocket(); -} - -////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -*/ - -// DCC VOICE NG proto - -// -// tcp control connection -// --> HELLO: DccVoice protocol header -// <-- HELLO: DccVoice protocol header -// --> IACCEPT: Codec-description|CodecId,Codec-description|CodecID,Codec... (in order of preference) -// <-- IACCEPT: Codec-description|CodecID,Codec-description|CodecId,Codec... (in order of preference) -// --> MYADDRESS -// <-- MYADDRESS -// --> YOURIDIS: (CID) -// <-- YOURIDIS: (CID) - -// Audio is sent in blocks broken in chunks broken in udp packets -// Each block is a set of consecutive audio chunks that theoretically -// should be played consecutively. -// Each packet in a chunk has an ordinal -// Chunks must be relatively short in order -// to allow a remote end that looses a packet to -// synchronize after a short period of time -// The maximum number of packets in a chunk is 65535 (but a chunk should be no more than 24-32 KBytes in size -// and in general they should be as small as possible, even one packet per chunk, if the codec allows it) -// Each chunk should be encoded independently of the others -// We can switch codec at each chunk (but not at each packet) -// When some packets are lost we loose the entire chunk -// A block is completly synchronized in time (unless we loose some chunks: in that case -// we may decide to synchronize with silence or insert a glitch...) -// Decoding never depends on the future - -// Each packet should be decompressable (eventually dependently on the previous in the chunk) -// but playable independently - -// start UDP stream - -// UDP Packet format: - -// : byte -// : byte -// : word -// : word -// - - -// Payload format: - -// : word -// : word (0 = beginning of a chunk) - -// read raw audio data at sample rate X, sample size Y -// multiplex data always at this sample rate and sample size - - -#endif - -#endif //_VOICE_H_ diff --git a/src/modules/dcc/window.cpp b/src/modules/dcc/window.cpp deleted file mode 100644 index 43d06e728..000000000 --- a/src/modules/dcc/window.cpp +++ /dev/null @@ -1,58 +0,0 @@ -//============================================================================= -// -// File : window.cpp -// Creation date : Fri Jul 26 02:04:40 2002 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "window.h" - -#include "KviTalHBox.h" - -KviDccWindow::KviDccWindow(int type,KviMainWindow * lpFrm,const char * name,KviDccDescriptor * d) -: KviWindow(type,lpFrm,name, d->console()) -{ - m_pDescriptor = d; - m_pDescriptor->setWindow(this); - m_pMarshal = 0; - m_pButtonBox = new KviTalHBox(this); - createTextEncodingButton(m_pButtonBox); -} - -KviDccWindow::~KviDccWindow() -{ - if(m_pMarshal)delete m_pMarshal; - if(m_pDescriptor)delete m_pDescriptor; -} - -KviWindow * KviDccWindow::dccMarshalOutputWindow() -{ - return this; -} - -const char * KviDccWindow::dccMarshalOutputContextString() -{ - static const char * static_context = "DCC"; - return static_context; -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_window.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/dcc/window.h b/src/modules/dcc/window.h deleted file mode 100644 index 601ab88b0..000000000 --- a/src/modules/dcc/window.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _WINDOW_H_ -#define _WINDOW_H_ -//============================================================================= -// -// File : window.h -// Creation date : Fri Jul 26 02:04:39 2002 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "descriptor.h" -#include "marshal.h" - -#include "KviWindow.h" -class KviDccThread; - -class KviDccWindow : public KviWindow, public KviDccMarshalOutputContext -{ - Q_OBJECT -public: - KviDccWindow(int type,KviMainWindow * lpFrm,const char * name,KviDccDescriptor * d); - ~KviDccWindow(); -protected: - KviDccDescriptor * m_pDescriptor; - KviDccMarshal * m_pMarshal; -public: - KviDccDescriptor * descriptor() { return m_pDescriptor; }; - const KviDccMarshal * marshal() { return m_pMarshal; }; - virtual KviDccThread * getSlaveThread() { return 0; }; - virtual KviWindow * dccMarshalOutputWindow(); - virtual const char * dccMarshalOutputContextString(); -}; - -#endif //_WINDOW_H_ diff --git a/src/modules/editor/CMakeLists.txt b/src/modules/editor/CMakeLists.txt index 239a32db6..a4eca8e01 100644 --- a/src/modules/editor/CMakeLists.txt +++ b/src/modules/editor/CMakeLists.txt @@ -1,12 +1,12 @@ # CMakeLists for src/modules/editor SET(kvieditor_MOC_HDRS - scripteditor.h + ScriptEditorImplementation.h ) SET(kvieditor_SRCS libkvieditor.cpp - scripteditor.cpp + ScriptEditorImplementation.cpp ) # After this call, files will be moc'ed to moc_kvi_*.cpp diff --git a/src/modules/editor/ScriptEditorImplementation.cpp b/src/modules/editor/ScriptEditorImplementation.cpp new file mode 100644 index 000000000..6bd4bed4a --- /dev/null +++ b/src/modules/editor/ScriptEditorImplementation.cpp @@ -0,0 +1,1137 @@ +//============================================================================= +// +// File : ScriptEditorImplementation.cpp +// Creation date : Sun Mar 28 1999 16:11:48 CEST by Szymon Stefanek +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 1999 Szymon Stefanek +// Copyright (C) 2005 Tonino Imbesi +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "ScriptEditorImplementation.h" + +#include "KviFileUtils.h" +#include "kvi_fileextensions.h" +#include "KviLocale.h" +#include "KviFileDialog.h" +#include "KviQString.h" +#include "KviConfigurationFile.h" +#include "KviModule.h" +#include "KviPointerList.h" +#include "KviApplication.h" +#include "KviConsoleWindow.h" +#include "KviWindow.h" +#include "KviIconManager.h" +#include "KviKvsKernel.h" +#include "KviModuleManager.h" +#include "KviConfigurationFile.h" +#include "KviTalVBox.h" +#include "KviTalHBox.h" +#include "KviTalGroupBox.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern KVIRC_API KviModuleManager * g_pModuleManager; +extern KviPointerList * g_pScriptEditorWindowList; +extern KviModule * g_pEditorModulePointer; + +static QColor g_clrBackground(0,0,0); +static QColor g_clrNormalText(100,255,0); +static QColor g_clrBracket(255,0,0); +static QColor g_clrComment(0,120,0); +static QColor g_clrFunction(255,255,0); +static QColor g_clrKeyword(120,120,150); +static QColor g_clrVariable(200,200,200); +static QColor g_clrPunctuation(180,180,0); +static QColor g_clrFind(255,0,0); + +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + #define KVI_SCRIPTEDITOR_DEFAULT_FONT "Courier New" +#else + #define KVI_SCRIPTEDITOR_DEFAULT_FONT "Monospace" +#endif +static QFont g_fntNormal(KVI_SCRIPTEDITOR_DEFAULT_FONT,8); + +static bool bSemaphore=false; +static bool bCompleterReady=false; + + +ScriptEditorWidget::ScriptEditorWidget(QWidget * pParent) +: QTextEdit(pParent) +{ + m_pSyntaxHighlighter=0; + setTabStopWidth(48); + setAcceptRichText(false); + setWordWrapMode(QTextOption::NoWrap); + m_pParent = pParent; + m_szHelp = "Nothing"; + updateOptions(); + m_szFind = ""; + m_pCompleter = 0; + QStringList szListFunctionsCommands; + QString tmp("kvscompleter.idx"); + iModulesCount=0; + iIndex=0; + QString szPath; + g_pApp->getLocalKvircDirectory(szPath,KviApplication::ConfigPlugins,tmp); + + if(!KviFileUtils::fileExists(szPath)) + { + if (!bSemaphore){ + bSemaphore=true; + m_pStartTimer = new QTimer(); + m_pStartTimer->setInterval(1000); + connect(m_pStartTimer,SIGNAL(timeout()),this,SLOT(asyncCompleterCreation())); + m_pStartTimer->start(500); + } + else{ + m_pStartTimer = new QTimer(); + m_pStartTimer->setInterval(2000); + connect(m_pStartTimer,SIGNAL(timeout()),this,SLOT(checkReadyCompleter())); + m_pStartTimer->start(1000); + } + } else loadCompleterFromFile(); +} + +ScriptEditorWidget::~ScriptEditorWidget() +{ + if(m_pCompleter) + delete m_pCompleter; + disableSyntaxHighlighter(); +} + +void ScriptEditorWidget::checkReadyCompleter() +{ + if(bCompleterReady) + { + m_pStartTimer->stop(); + delete m_pStartTimer; + m_pStartTimer=0; + loadCompleterFromFile(); + } +} + +void ScriptEditorWidget::asyncCompleterCreation() +{ + //static int iIndex = 0; + //static int iModulesCount = 0; + if(!iIndex) + { + m_pListCompletition = new QStringList(); + QString szPath; + + g_pApp->getGlobalKvircDirectory(szPath,KviApplication::Modules); + + QDir d(szPath); + +#if defined(COMPILE_ON_WINDOWS) + d.setNameFilters(QStringList("kvi*.dll")); +#elif defined(COMPILE_ON_MINGW) + d.setNameFilters(QStringList("libkvi*.dll")); +#else + d.setNameFilters(QStringList("libkvi*.so")); +#endif + m_pListModulesNames = new QStringList(d.entryList(QDir::Files | QDir::Readable)); + iModulesCount = m_pListModulesNames->count(); + } + QString szModuleName = m_pListModulesNames->at(iIndex); + iIndex++; + +#if defined(COMPILE_ON_WINDOWS) + szModuleName=szModuleName.replace("kvi",""); + szModuleName=szModuleName.replace(".dll",""); +#elif defined(COMPILE_ON_MINGW) + szModuleName=szModuleName.replace("libkvi",""); + szModuleName=szModuleName.replace(".dll",""); +#else + szModuleName=szModuleName.replace("libkvi",""); + szModuleName=szModuleName.replace(".so",""); +#endif + + KviModule * pModule = g_pModuleManager->getModule(szModuleName); + if(pModule) + { + pModule->getAllFunctionsCommandsModule(m_pListCompletition,szModuleName); + } + + if(iIndex == iModulesCount) + { + m_pStartTimer->stop(); + m_pStartTimer->deleteLater(); + m_pStartTimer = 0; + QString szTmp("kvscompleter.idx"); + QString szPath; + g_pApp->getLocalKvircDirectory(szPath,KviApplication::ConfigPlugins,szTmp); + KviKvsKernel::instance()->getAllFunctionsCommandsCore(m_pListCompletition); + QString szBuffer = m_pListCompletition->join(","); + QFile f(szPath); + f.open(QIODevice::WriteOnly); + f.write(szBuffer.toUtf8()); + f.close(); + createCompleter(*m_pListCompletition); + iIndex = 0; + iModulesCount = 0; + bCompleterReady=true; + delete m_pListCompletition; + delete m_pListModulesNames; + } +} + +void ScriptEditorWidget::loadCompleterFromFile() +{ + QStringList szListFunctionsCommand; + QString szTmp("kvscompleter.idx"); + QString szPath; + g_pApp->getLocalKvircDirectory(szPath,KviApplication::ConfigPlugins,szTmp); + QString szBuffer; + QFile f(szPath); + f.open(QIODevice::ReadOnly); + szBuffer = f.readAll(); + f.close(); + szListFunctionsCommand = szBuffer.split(','); + createCompleter(szListFunctionsCommand); +} + +void ScriptEditorWidget::createCompleter(QStringList & list) +{ + m_pCompleter = new QCompleter(list); + m_pCompleter->setCaseSensitivity(Qt::CaseInsensitive); + m_pCompleter->setWrapAround(false); + m_pCompleter->setWidget(this); + m_pCompleter->setModelSorting(QCompleter::CaseSensitivelySortedModel); + m_pCompleter->setCompletionMode(QCompleter::PopupCompletion); + m_pCompleter->setCaseSensitivity(Qt::CaseInsensitive); + QObject::connect(m_pCompleter, SIGNAL(activated(const QString &)),this, SLOT(insertCompletion(const QString &))); +} + +void ScriptEditorWidget::insertCompletion(const QString & szCompletion) +{ + QTextCursor tc = textCursor(); + int iExtra = szCompletion.length() - m_pCompleter->completionPrefix().length(); + + tc.movePosition(QTextCursor::Left); + tc.movePosition(QTextCursor::EndOfWord); + + QString szTmp = szCompletion.right(iExtra); + if(szCompletion.left(1)=="$") + szTmp.append("("); + else + szTmp.append(" "); + + tc.insertText(szTmp); + setTextCursor(tc); +} + +void ScriptEditorWidget::contextMenuEvent(QContextMenuEvent * e) +{ + QMenu * pMenu = createStandardContextMenu(); + pMenu->addAction(__tr2qs_ctx("Context sensitive help","editor"),this,SLOT(slotHelp()),Qt::CTRL+Qt::Key_H); + pMenu->addAction(__tr2qs_ctx("&Replace","editor"),this,SLOT(slotReplace()),Qt::CTRL+Qt::Key_R); + pMenu->exec(e->globalPos()); + delete pMenu; +} + +void ScriptEditorWidget::slotFind() +{ + m_szFind = ((ScriptEditorImplementation*)m_pParent)->findLineEdit()->text(); + setText(toPlainText()); +} + +void ScriptEditorWidget::slotReplace() +{ + ScriptEditorReplaceDialog * pDialog = new ScriptEditorReplaceDialog(this,__tr2qs_ctx("Find & Replace","editor")); + connect(pDialog,SIGNAL(replaceAll(const QString &,const QString &)),m_pParent,SLOT(slotReplaceAll(const QString &,const QString &))); + connect(pDialog,SIGNAL(initFind()),m_pParent,SLOT(slotInitFind())); + connect(pDialog,SIGNAL(nextFind(const QString &)),m_pParent,SLOT(slotNextFind(const QString &))); + + if(pDialog->exec()){}; +} + +void ScriptEditorWidget::slotHelp() +{ + contextSensitiveHelp(); +} +void ScriptEditorWidget::enableSyntaxHighlighter() +{ + // we currently delete and re-create the m_pSyntaxHighlighter + // as a trick to ensure proper re-highlightning to occur + if (!m_pSyntaxHighlighter) + m_pSyntaxHighlighter = new ScriptEditorSyntaxHighlighter(this); +} +void ScriptEditorWidget::disableSyntaxHighlighter() +{ + if (m_pSyntaxHighlighter) delete m_pSyntaxHighlighter; + m_pSyntaxHighlighter = 0; +} + +void ScriptEditorWidget::updateOptions() +{ + QPalette p = palette(); + p.setColor(QPalette::Base,g_clrBackground); + p.setColor(QPalette::Text,g_clrNormalText); + setPalette(p); + setFont(g_fntNormal); + setTextColor(g_clrNormalText); + disableSyntaxHighlighter(); + enableSyntaxHighlighter(); + + p = ((ScriptEditorImplementation*)m_pParent)->findLineEdit()->palette(); + p.setColor(foregroundRole(),g_clrFind); + ((ScriptEditorImplementation*)m_pParent)->findLineEdit()->setPalette(p); +} + +void ScriptEditorWidget::keyPressEvent(QKeyEvent * e) +{ + if(m_pCompleter && m_pCompleter->popup()->isVisible()) + { + switch(e->key()) + { + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_Escape: + case Qt::Key_Tab: + case Qt::Key_Backtab: + e->ignore(); + return; + default: + break; + } + } + + if(e->modifiers() == Qt::ControlModifier) + { + switch(e->key()) + { + case Qt::Key_B: + insertPlainText("$b"); + return; + case Qt::Key_K: + insertPlainText("$k"); + return; + case Qt::Key_O: + insertPlainText("$o"); + return; + case Qt::Key_U: + insertPlainText("$u"); + return; + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_PageUp: + e->ignore(); // allow the parent to process it + return; + break; + } + } +// Adapted from QT4 QCompleter example + bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E); // CTRL+E + if (!m_pCompleter || !isShortcut) // don't process the shortcut when we have a completer + QTextEdit::keyPressEvent(e); + const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier); + if (!m_pCompleter || (ctrlOrShift && e->text().isEmpty())) + return; + static QString eow("~!@#$%^&*()_+{}|:\"<>?,/;'[]\\-="); // end of word + bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift; + QString completionPrefix = textUnderCursor(); + if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 3 || eow.contains(e->text().right(1)))) + { + m_pCompleter->popup()->hide(); + return; + } + if (completionPrefix != m_pCompleter->completionPrefix()) + { + m_pCompleter->setCompletionPrefix(completionPrefix); + m_pCompleter->popup()->setCurrentIndex(m_pCompleter->completionModel()->index(0, 0)); + } + QRect cr = cursorRect(); + cr.setWidth(m_pCompleter->popup()->sizeHintForColumn(0)+ m_pCompleter->popup()->verticalScrollBar()->sizeHint().width()); + m_pCompleter->complete(cr); +} + +QString ScriptEditorWidget::textUnderCursor() const +{ + QString szWord; + QTextCursor tc = textCursor(); + if(tc.atBlockStart()) + return QString(); + tc.clearSelection(); + tc.movePosition(QTextCursor::StartOfWord,QTextCursor::KeepAnchor); + if(tc.atBlockStart()) + { + szWord.append(tc.selectedText()); + tc.movePosition(QTextCursor::EndOfWord,QTextCursor::KeepAnchor); + szWord.append(tc.selectedText()); + if(tc.atBlockEnd()){ + return szWord; + } + tc.movePosition(QTextCursor::NextCharacter,QTextCursor::KeepAnchor); + szWord.append(tc.selectedText()); + if(szWord.right(1)!=".") + szWord.chop(1); + return szWord; + } + + tc.movePosition(QTextCursor::PreviousCharacter,QTextCursor::KeepAnchor); + szWord=tc.selectedText(); + if(szWord.left(1)==".") + { + tc.movePosition(QTextCursor::StartOfWord); + tc.movePosition(QTextCursor::PreviousCharacter); + tc.movePosition(QTextCursor::PreviousWord); + tc.movePosition(QTextCursor::EndOfWord,QTextCursor::KeepAnchor,1); + szWord.prepend(tc.selectedText()); + } else szWord.remove(0,1); + return szWord; +} +/* +void ScriptEditorWidget::mouseReleaseEvent(QMouseEvent * e) +{ + + return; + QRect r = cursorRect(); + QTextCursor cur = cursorForPosition(e->pos()); + // cur.select( + + + //completelistbox->hide(); + if (e->button() == Qt::RightButton) + { + QString szBuffer; + /\* + int iPara = paragraphAt(e->pos()); + int iIndex=charAt(e->pos(),&iPara); + szBuffer = this->text(iPara); + getWordOnCursor(szBuffer,iIndex); + *\/ + QRect r = cursorRect(); + QTextCursor cur = cursorForPosition(e->pos()); + cur.select(QTextCursor::WordUnderCursor); + szBuffer = cur.selectedText(); + QString szTmp = szBuffer; + KviPointerList * pList; + if(szTmp.left(1) == "$") + { + szTmp.remove(0,1); + pList = KviKvsKernel::instance()->completeCommandAllocateResult(szTmp); + if (pList->count() != 1) + szBuffer = ""; + else + szBuffer = *(pList->at(0)); + } else { + pList = KviKvsKernel::instance()->completeCommandAllocateResult(szTmp); + if (pList->count() != 1) + szBuffer = ""; + else + szBuffer = *(pList->at(0)); + } + + for (unsigned int i=0; i < pList->count(); i++) + QString str = *(pList->at(i)); + + KviKvsKernel::instance()->freeCompletionResult(pList); + m_szHelp = szBuffer; + } + + QTextEdit::mouseReleaseEvent(e); +} +*/ +bool ScriptEditorWidget::contextSensitiveHelp() const +{ + /* + QString szBuffer; + int iPara, iIndex; + getCursorPosition(&iPara,&iIndex); + szBuffer = text(iPara); + getWordOnCursor(szBuffer,iIndex); + */ + + QRect r = cursorRect(); + QTextCursor cur = cursorForPosition(QPoint(r.x(),r.y())); + cur.select(QTextCursor::WordUnderCursor); + QString szText = cur.selectedText(); + QString szTmp = szText; + /* + KviPointerList * pList; + if(szTmp.left(1) == "$") + { + szTmp.remove(0,1); + pList = g_pUserParser->completeFunctionAllocateResult(szTmp); + } else { + pList = g_pUserParser->completeCommandAllocateResult(szTmp); + } + qDebug("command or func %s",szTmp.toUtf8().data()); + + bool bOk = false; + if(pList) + { + for(QString * s = pList->first(); s; s = pList->next()) + { + if(KviQString::equalCI(*s,szBuffer)) + { + pList->last(); + bOk = true; + } + } + } + + g_pUserParser->freeCompletionResult(pList); + if(!bOk)return false; + + QString szParse; + KviQString::sprintf(szParse,"timer -s (help,0){ help -s %Q; }",&szBuffer); + qDebug("parsing %s",szParse.toLatin1()); + KviKvsScript::run(szParse,(KviWindow*)g_pApp->activeConsole()); + */ + + return true; +} + +ScriptEditorWidgetColorOptions::ScriptEditorWidgetColorOptions(QWidget * pParent) +: QDialog(pParent) +{ + m_pSelectorInterfaceList = new KviPointerList; + m_pSelectorInterfaceList->setAutoDelete(false); + setWindowTitle(__tr2qs_ctx("Preferences","editor")); + QGridLayout * g = new QGridLayout(this); + KviTalVBox * box = new KviTalVBox(this); + g->addWidget(box,0,0); + box->setMargin(0); + box->setSpacing(0); + KviFontSelector * f = new KviFontSelector(box,__tr2qs_ctx("Font:","editor"),&g_fntNormal,true); + m_pSelectorInterfaceList->append(f); + KviTalGroupBox * gbox = new KviTalGroupBox(Qt::Horizontal,__tr2qs_ctx("Colors","editor"),box); + gbox->setInsideSpacing(0); + + addColorSelector(gbox,__tr2qs_ctx("Background:","editor"),&g_clrBackground,true); + addColorSelector(gbox,__tr2qs_ctx("Normal text:","editor"),&g_clrNormalText,true); + addColorSelector(gbox,__tr2qs_ctx("Brackets:","editor"),&g_clrBracket,true); + addColorSelector(gbox,__tr2qs_ctx("Comments:","editor"),&g_clrComment,true); + addColorSelector(gbox,__tr2qs_ctx("Functions:","editor"),&g_clrFunction,true); + addColorSelector(gbox,__tr2qs_ctx("Keywords:","editor"),&g_clrKeyword,true); + addColorSelector(gbox,__tr2qs_ctx("Variables:","editor"),&g_clrVariable,true); + addColorSelector(gbox,__tr2qs_ctx("Punctuation:","editor"),&g_clrPunctuation,true); + addColorSelector(gbox,__tr2qs_ctx("Find:","editor"),&g_clrFind,true); + + KviTalHBox * hbox = new KviTalHBox(box); + + QPushButton * b = new QPushButton(__tr2qs_ctx("OK","editor"),hbox); + b->setDefault(true); + connect(b,SIGNAL(clicked()),this,SLOT(okClicked())); + + b = new QPushButton(__tr2qs_ctx("Cancel","editor"),hbox); + connect(b,SIGNAL(clicked()),this,SLOT(reject())); +} + +ScriptEditorWidgetColorOptions::~ScriptEditorWidgetColorOptions() +{ + delete m_pSelectorInterfaceList; +} + +KviColorSelector * ScriptEditorWidgetColorOptions::addColorSelector(QWidget * pParent,const QString & txt,QColor * pOption,bool bEnabled) +{ + KviColorSelector * s = new KviColorSelector(pParent,txt,pOption,bEnabled); + m_pSelectorInterfaceList->append(s); + return s; +} + +void ScriptEditorWidgetColorOptions::okClicked() +{ + for(KviSelectorInterface * i = m_pSelectorInterfaceList->first();i;i = m_pSelectorInterfaceList->next()) + { + i->commit(); + } + accept(); +} + + +ScriptEditorSyntaxHighlighter::ScriptEditorSyntaxHighlighter(ScriptEditorWidget * pWidget) +: QSyntaxHighlighter(pWidget),m_pTextEdit(pWidget) +{ + // code adpated from QT4 example + + // FIX-ME: "function ..." - "function internal ..." + // FIX-ME: "@$" + // FIX-ME: "\" escape char + updateSyntaxtTextFormat(); + + KviScriptHighlightingRule rule; + + rule.pattern=QRegExp("([=()[\\]!\"?<>;:.,+-])+"); + rule.format=punctuationFormat; + highlightingRules.append(rule); + + rule.pattern=QRegExp("[{};](|[a-zA-Z]|[a-zA-Z]+[a-zA-Z0-9_\\.:]*)"); + rule.format=keywordFormat; + highlightingRules.append(rule); + + + rule.pattern=QRegExp("[$](|[a-zA-Z0-9]+[a-zA-Z0-9_\\.:]*)"); + rule.format=functionFormat; + highlightingRules.append(rule); + + rule.pattern=QRegExp("[%](|[a-zA-Z]|[a-zA-Z]+[a-zA-Z0-9_\\.]*)"); + rule.format=variableFormat; + highlightingRules.append(rule); + + rule.pattern=QRegExp("([{}])+"); + rule.format=bracketFormat; + highlightingRules.append(rule); +} + +ScriptEditorSyntaxHighlighter::~ScriptEditorSyntaxHighlighter() +{ +} + +void ScriptEditorSyntaxHighlighter::updateSyntaxtTextFormat() +{ + punctuationFormat.setForeground(g_clrPunctuation); + keywordFormat.setForeground(g_clrKeyword); + functionFormat.setForeground(g_clrFunction); + variableFormat.setForeground(g_clrVariable); + bracketFormat.setForeground(g_clrBracket); + commentFormat.setForeground(g_clrComment); + findFormat.setForeground(g_clrFind); +} + +#define SKIP_SPACES \ + while(iIndexStart < szText.size()) \ + { \ + if(szText.at(iIndexStart).unicode()=='\t' || szText.at(iIndexStart).unicode()==' ') \ + { \ + iIndexStart++; \ + } else { \ + break; \ + } \ + } \ + +void ScriptEditorSyntaxHighlighter::highlightBlock(const QString & szText) +{ + if(szText.isEmpty()) + { + setCurrentBlockState(previousBlockState()); + return; + } + + int iIndexStart=0; + setCurrentBlockState(0); + + if(previousBlockState() == 1) + { + // inside a multiline comment + int iCommentEnd = szText.indexOf("*/"); + if(iCommentEnd < 0) + { + // not found: comment until the end of the block + setCurrentBlockState(1); + setFormat(iIndexStart,szText.length(),commentFormat); + return; + } + // skip 2 chars + iCommentEnd+=2; + // end of comment found + setFormat(iIndexStart,iCommentEnd - iIndexStart,commentFormat); + iIndexStart = iCommentEnd; + } + + SKIP_SPACES + + if (iIndexStart == szText.size()) + return; + + // check 'commands' and comments + int iCommandStart=iIndexStart; + if (szText.at(iIndexStart).unicode()!='$' && szText.at(iIndexStart).unicode()!='{' && szText.at(iIndexStart).unicode()!='}' && szText.at(iIndexStart).unicode()!='%') + { + switch(szText.at(iIndexStart).unicode()) + { + case '#': + // single line comment, bash style + while(iIndexStart= 0) + { + int length = expression.matchedLength(); + setFormat(index, length, rule.format); + index = szText.indexOf(expression, index + length); + } + } + + // 'found matches' highlighting + ScriptEditorWidget * pEditor = ((ScriptEditorWidget *)textEdit()); + QString szFind = pEditor->m_szFind; + if (!szFind.isEmpty()) + { + index = szText.indexOf(szFind,0,Qt::CaseInsensitive); + int length=szFind.length(); + while (index >= 0) + { + setFormat(index, length, findFormat); + index = szText.indexOf(szFind,index + length,Qt::CaseInsensitive); + } + } +} + + +ScriptEditorImplementation::ScriptEditorImplementation(QWidget * par) +:KviScriptEditor(par) +{ + m_pOptionsDialog=0; + if(g_pScriptEditorWindowList->isEmpty())loadOptions(); + g_pScriptEditorWindowList->append(this); + m_lastCursorPos = 0; + QGridLayout * g = new QGridLayout(this); + + m_pFindLineEdit = new QLineEdit(" ",this); + m_pFindLineEdit->setText(""); + + QPalette p = m_pFindLineEdit->palette(); + p.setColor(foregroundRole(), g_clrFind); + m_pFindLineEdit->setPalette(p); + + m_pEditor = new ScriptEditorWidget(this); + + g->addWidget(m_pEditor, 0, 0, 1,4); + g->setRowStretch(0,1); + + QToolButton * b = new QToolButton(this); + b->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_OPTIONS))); + + b->setObjectName("ToolButtonEditor"); + b->setMinimumWidth(24); + g->addWidget(b,1,0); + + KviTalPopupMenu * pop = new KviTalPopupMenu(b); + pop->insertItem(__tr2qs_ctx("&Open...","editor"),this,SLOT(loadFromFile())); + pop->insertItem(__tr2qs_ctx("&Save As...","editor"),this,SLOT(saveToFile())); + pop->insertSeparator(); + pop->insertItem(__tr2qs_ctx("&Configure Editor...","editor"),this,SLOT(configureColors())); + b->setMenu(pop); + b->setPopupMode(QToolButton::InstantPopup); + + g->setColumnStretch(1,1); + g->setColumnStretch(2,10); + g->addWidget(m_pFindLineEdit,1,2); + + QLabel * pLab = new QLabel(this); + pLab->setText(__tr2qs_ctx("Find","editor")); + g->addWidget(pLab,1,1); + + m_pRowColLabel = new QLabel("0",this); + m_pRowColLabel->setFrameStyle(QFrame::Sunken | QFrame::Panel); + m_pRowColLabel->setMinimumWidth(80); + g->addWidget(m_pRowColLabel,1,3); + + connect(m_pFindLineEdit,SIGNAL(returnPressed()),m_pEditor,SLOT(slotFind())); + connect(m_pFindLineEdit,SIGNAL(returnPressed()),this,SLOT(slotFind())); + connect(m_pEditor,SIGNAL(cursorPositionChanged()),this,SLOT(updateRowColLabel())); + connect(m_pEditor,SIGNAL(selectionChanged()),this,SLOT(updateRowColLabel())); + m_lastCursorPos = 0; +} + +ScriptEditorImplementation::~ScriptEditorImplementation() +{ + if(m_pOptionsDialog) + { + m_pOptionsDialog->deleteLater(); + m_pOptionsDialog=0; + } + g_pScriptEditorWindowList->removeRef(this); + if(g_pScriptEditorWindowList->isEmpty()) + saveOptions(); +} + +void ScriptEditorImplementation::loadOptions() +{ + QString szTmp; + g_pEditorModulePointer->getDefaultConfigFileName(szTmp); + + KviConfigurationFile cfg(szTmp,KviConfigurationFile::Read); + g_clrBackground = cfg.readColorEntry("Background",QColor(0,0,0));; + g_clrNormalText = cfg.readColorEntry("NormalText",QColor(100,255,0)); + g_clrBracket = cfg.readColorEntry("Bracket",QColor(255,0,0)); + g_clrComment = cfg.readColorEntry("Comment",QColor(0,120,0)); + g_clrFunction = cfg.readColorEntry("Function",QColor(255,255,0)); + g_clrKeyword = cfg.readColorEntry("Keyword",QColor(120,120,150)); + g_clrVariable = cfg.readColorEntry("Variable",QColor(200,200,200)); + g_clrPunctuation = cfg.readColorEntry("Punctuation",QColor(180,180,0)); + g_clrFind = cfg.readColorEntry("Find",QColor(255,0,0)); + g_fntNormal = cfg.readFontEntry("Font",QFont(KVI_SCRIPTEDITOR_DEFAULT_FONT,8)); +} + +bool ScriptEditorImplementation::isModified() +{ + return m_pEditor->document()->isModified(); +} +void ScriptEditorImplementation::setModified(bool bModified) +{ + return m_pEditor->document()->setModified(bModified); +} +void ScriptEditorImplementation::slotFind() +{ + emit find(m_pFindLineEdit->text()); +} + +void ScriptEditorImplementation::slotNextFind(const QString &) //szText +{ +// emit nextFind(const QString & szText); +} + +void ScriptEditorImplementation::slotInitFind() +{ + emit initFind(); +} + +void ScriptEditorImplementation::slotReplaceAll(const QString & szToReplace, const QString & szReplaceWith) +{ + emit replaceAll(szToReplace,szReplaceWith); +} + +void ScriptEditorImplementation::saveOptions() +{ + QString szTmp; + g_pEditorModulePointer->getDefaultConfigFileName(szTmp); + + KviConfigurationFile cfg(szTmp,KviConfigurationFile::Write); + cfg.writeEntry("Background",g_clrBackground);; + cfg.writeEntry("NormalText",g_clrNormalText); + cfg.writeEntry("Bracket",g_clrBracket); + cfg.writeEntry("Comment",g_clrComment); + cfg.writeEntry("Function",g_clrFunction); + cfg.writeEntry("Keyword",g_clrKeyword); + cfg.writeEntry("Variable",g_clrVariable); + cfg.writeEntry("Punctuation",g_clrPunctuation); + cfg.writeEntry("Find",g_clrFind); + cfg.writeEntry("Font",g_fntNormal); +} + +void ScriptEditorImplementation::setFocus() +{ + m_pEditor->setFocus(); +} + +void ScriptEditorImplementation::focusInEvent(QFocusEvent *) +{ + m_pEditor->setFocus(); +} + +void ScriptEditorImplementation::setEnabled(bool bEnabled) +{ + QWidget::setEnabled(bEnabled); + m_pEditor->setEnabled(bEnabled); + m_pRowColLabel->setEnabled(bEnabled); +} + +void ScriptEditorImplementation::saveToFile() +{ + QString szFileName; + if(KviFileDialog::askForSaveFileName(szFileName, + __tr2qs_ctx("Choose a Filename - KVIrc","editor"), + QString::null, + QString::null,false,true,true)) + { + QString szBuffer = m_pEditor->toPlainText(); + + //if(tmp.isEmpty())tmp = ""; + //KviCString buffer = tmp.toUtf8().data(); + if(!KviFileUtils::writeFile(szFileName,szBuffer)) + { + QString szTmp; + QMessageBox::warning(this, + __tr2qs_ctx("Save Failed - KVIrc","editor"), + KviQString::sprintf(szTmp,__tr2qs_ctx("Can't open the file %s for writing.","editor"),&szFileName)); + } + } +} + +void ScriptEditorImplementation::setText(const char * txt) +{ + setText(QByteArray(txt)); +} +void ScriptEditorImplementation::setUnHighlightedText(const QString & szText) +{ + m_pEditor->disableSyntaxHighlighter(); + m_pEditor->setText(szText); +} +void ScriptEditorImplementation::setText(const QByteArray & szText) +{ + m_pEditor->setPlainText(szText.data()); + m_pEditor->document()->setModified(false); + updateRowColLabel(); +} +void ScriptEditorImplementation::setReadOnly(bool bReadOnly) +{ + m_pEditor->setReadOnly(bReadOnly); +} +void ScriptEditorImplementation::getText(QByteArray & szText) +{ + szText = m_pEditor->toPlainText().toUtf8(); +} + +void ScriptEditorImplementation::setText(const QString & szText) +{ + m_pEditor->enableSyntaxHighlighter(); + m_pEditor->setPlainText(szText); + QTextCursor cur=m_pEditor->textCursor(); + cur.movePosition(QTextCursor::End); + m_pEditor->setTextCursor(cur); + m_pEditor->document()->setModified(false); + updateRowColLabel(); +} + +void ScriptEditorImplementation::getText(QString & szText) +{ + szText = m_pEditor->toPlainText(); +} + +void ScriptEditorImplementation::setFindText(const QString & szText) +{ + m_pFindLineEdit->setText(szText); + m_pEditor->slotFind(); +} + +void ScriptEditorImplementation::updateRowColLabel() +{ + if(m_lastCursorPos==m_pEditor->textCursor().position()) + return; + int iRow = m_pEditor->textCursor().blockNumber(); + int iCol = m_pEditor->textCursor().columnNumber(); + QString szTmp; + KviQString::sprintf(szTmp,__tr2qs_ctx("Row: %d Col: %d","editor"),iRow,iCol); + m_pRowColLabel->setText(szTmp); + m_lastCursorPos = m_pEditor->textCursor().position(); +} + +void ScriptEditorImplementation::setCursorPosition(int iPos) +{ + QTextCursor cur = m_pEditor->textCursor(); + cur.setPosition(iPos); + m_pEditor->setTextCursor(cur); + updateRowColLabel(); +} + +void ScriptEditorImplementation::loadFromFile() +{ + QString szFileName; + if(KviFileDialog::askForOpenFileName(szFileName, + __tr2qs_ctx("Load Script File - KVIrc","editor"), + QString::null,KVI_FILTER_SCRIPT,false,true)) + { + QString szBuffer; + if(KviFileUtils::loadFile(szFileName,szBuffer)) + { + m_pEditor->setPlainText(szBuffer); + setCursorPosition(0); + //m_pEditor->moveCursor(QTextEdit::MoveEnd,false); + //updateRowColLabel(); + } else { + QString szTmp; + QMessageBox::warning(this, + __tr2qs_ctx("Open Failed - KVIrc","editor"), + KviQString::sprintf(szTmp,__tr2qs_ctx("Can't open the file %s for reading.","editor"),&szFileName)); + } + } +} + +void ScriptEditorImplementation::configureColors() +{ + if(!m_pOptionsDialog) + { + m_pOptionsDialog = new ScriptEditorWidgetColorOptions(this); + connect(m_pOptionsDialog,SIGNAL(finished(int)),this,SLOT(optionsDialogFinished(int))); + } + m_pOptionsDialog->show(); +} + +void ScriptEditorImplementation::optionsDialogFinished(int iResult) +{ + if(iResult == QDialog::Accepted) + { + m_pEditor->updateOptions(); + saveOptions(); + } +} + +ScriptEditorReplaceDialog::ScriptEditorReplaceDialog(QWidget * pParent, const QString & szName) +: QDialog(pParent) +{ + setObjectName(szName); + + m_pParent = pParent; + emit initFind(); + QPalette p = palette(); + p.setColor(foregroundRole(),QColor( 0, 0, 0 )); + p.setColor(backgroundRole(),QColor( 236, 233, 216 )); + setPalette(p); + + QGridLayout * pLayout = new QGridLayout(this); + pLayout->setObjectName("replace layout"); + + QLabel * m_pFindLabel = new QLabel(this); + m_pFindLabel->setObjectName("findlabel"); + m_pFindLabel->setText(__tr2qs_ctx("Word to Find","editor")); + pLayout->addWidget(m_pFindLabel,0,0); + + m_pFindLineEdit = new QLineEdit(this); + m_pFindLineEdit->setObjectName("findlineedit"); + pLayout->addWidget(m_pFindLineEdit,0,1); + + QLabel * m_pReplaceLabel = new QLabel(this); + m_pReplaceLabel->setObjectName("replacelabel"); + m_pReplaceLabel->setText(__tr2qs_ctx("Replace with","editor")); + pLayout->addWidget(m_pReplaceLabel,1,0); + + m_pReplaceLineEdit = new QLineEdit(this); + m_pReplaceLineEdit->setObjectName("replacelineedit"); + pLayout->addWidget(m_pReplaceLineEdit,1,1); + + + m_pFindLineEdit->setFocus(); + + m_pCheckReplaceAll = new QCheckBox(this); + m_pCheckReplaceAll->setObjectName("replaceAll"); + m_pCheckReplaceAll->setText(__tr2qs_ctx("&Replace in all editor's items","editor")); + pLayout->addWidget(m_pCheckReplaceAll,2,0); + + QPushButton * pCancelButton = new QPushButton(this); + pCancelButton->setObjectName("cancelButton"); + pCancelButton->setText(__tr2qs_ctx("&Cancel","editor")); + pLayout->addWidget(pCancelButton,3,0); + + m_pReplaceButton = new QPushButton(this); + m_pReplaceButton->setObjectName("replacebutton"); + m_pReplaceButton->setText(__tr2qs_ctx("&Replace","editor")); + m_pReplaceButton->setEnabled(false); + pLayout->addWidget(m_pReplaceButton,3,1); + + setLayout(pLayout); + + // signals and slots connections + connect(m_pReplaceButton, SIGNAL(clicked()), this, SLOT(slotReplace())); + connect(pCancelButton, SIGNAL(clicked()), this, SLOT(reject())); + connect(m_pFindLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged(const QString &))); +} + +ScriptEditorReplaceDialog::~ScriptEditorReplaceDialog() +{ +} + +void ScriptEditorReplaceDialog::textChanged(const QString & szText) +{ + if(!szText.isEmpty()) + m_pReplaceButton->setEnabled(true); + else + m_pReplaceButton->setEnabled(false); +} + +void ScriptEditorReplaceDialog::slotReplace() +{ + QString szText = ((ScriptEditorWidget *)m_pParent)->toPlainText(); + if(m_pCheckReplaceAll->isChecked()) + emit replaceAll(m_pFindLineEdit->text(),m_pReplaceLineEdit->text()); + + szText.replace(m_pFindLineEdit->text(),m_pReplaceLineEdit->text(),Qt::CaseInsensitive); + ((ScriptEditorWidget *)m_pParent)->setText(szText); + ((ScriptEditorWidget *)m_pParent)->document()->setModified(true); + m_pFindLineEdit->setText(""); + m_pReplaceLineEdit->setText(""); + setTabOrder(m_pFindLineEdit,m_pReplaceLineEdit); +} + +void ScriptEditorReplaceDialog::slotNextFind() +{ + emit nextFind(m_pFindLineEdit->text()); +} diff --git a/src/modules/editor/ScriptEditorImplementation.h b/src/modules/editor/ScriptEditorImplementation.h new file mode 100644 index 000000000..50fcb3ca6 --- /dev/null +++ b/src/modules/editor/ScriptEditorImplementation.h @@ -0,0 +1,219 @@ +#ifndef _SCRIPTEDITOR_H_ +#define _SCRIPTEDITOR_H_ + +//============================================================================= +// +// File : ScriptEditorImplementation.h +// Creation date : Sun Mar 28 1999 16:11:48 CEST by Szymon Stefanek +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 1999-2010 Szymon Stefanek +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviScriptEditor.h" +#include "KviPointerList.h" +#include "KviSelectors.h" +#include "KviTalPopupMenu.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class QTimer; + +//typedef KviPointerList ColumnList; +class ScriptEditorSyntaxHighlighter; +class ScriptEditorWidget : public QTextEdit +{ + Q_OBJECT + Q_PROPERTY(bool contextSensitiveHelp READ contextSensitiveHelp) +public: + ScriptEditorWidget(QWidget * pParent); + virtual ~ScriptEditorWidget(); +public: + QString m_szFind; +protected: + ScriptEditorSyntaxHighlighter * m_pSyntaxHighlighter; + QCompleter * m_pCompleter; + QStringList * m_pListModulesNames; + QStringList * m_pListCompletition; + QTimer * m_pStartTimer; + QWidget * m_pParent; + int iIndex,iModulesCount; + QString m_szHelp; +public: + ScriptEditorSyntaxHighlighter * syntaxHighlighter(){return m_pSyntaxHighlighter;}; + void disableSyntaxHighlighter(); + void enableSyntaxHighlighter(); + + void createCompleter(QStringList &list); + + void loadCompleterFromFile(); + QCompleter * completer() const { return m_pCompleter; }; + QString textUnderCursor() const; + void updateOptions(); + //void find1(); + bool contextSensitiveHelp() const; +public slots: + void checkReadyCompleter(); + void insertCompletion(const QString & szCompletion); + void slotFind(); + void slotHelp(); + void slotReplace(); +protected slots: + void asyncCompleterCreation(); +signals: + void keyPressed(); +protected: + void contextMenuEvent(QContextMenuEvent * e); + virtual void keyPressEvent(QKeyEvent * e); +// void mouseReleaseEvent(QMouseEvent * e); +}; + +class ScriptEditorWidgetColorOptions : public QDialog +{ + Q_OBJECT +public: + ScriptEditorWidgetColorOptions(QWidget * pParent); + ~ScriptEditorWidgetColorOptions(); +private: + KviPointerList * m_pSelectorInterfaceList; +protected: + KviColorSelector * addColorSelector(QWidget * pParent,const QString & txt,QColor * pOption,bool bEnabled); + +protected slots: + void okClicked(); + +}; + +class ScriptEditorSyntaxHighlighter : public QSyntaxHighlighter +{ +public: + ScriptEditorSyntaxHighlighter(ScriptEditorWidget * pWidget); + virtual ~ScriptEditorSyntaxHighlighter(); +public: + QTextEdit * m_pTextEdit; +public: + QTextEdit * textEdit(){ return m_pTextEdit; } + void highlightBlock(const QString & szText); + void updateSyntaxtTextFormat(); +private: + struct KviScriptHighlightingRule + { + QRegExp pattern; + QTextCharFormat format; + }; + + QVector highlightingRules; + QRegExp commentStartExpression; + QRegExp commentEndExpression; + + QTextCharFormat bracketFormat; + QTextCharFormat punctuationFormat; + QTextCharFormat keywordFormat; + QTextCharFormat variableFormat; + QTextCharFormat normaltextFormat; + QTextCharFormat findFormat; + QTextCharFormat functionFormat; + QTextCharFormat commentFormat; +}; + +class ScriptEditorImplementation : public KviScriptEditor +{ + Q_OBJECT +public: + ScriptEditorImplementation(QWidget * par); + virtual ~ScriptEditorImplementation(); +public: + QLineEdit * m_pFindLineEdit; +protected: + ScriptEditorWidgetColorOptions * m_pOptionsDialog; + ScriptEditorWidget * m_pEditor; + QLabel * m_pRowColLabel; + int m_lastCursorPos; +public: + virtual void setText(const char * txt); + virtual void setText(const QString & szText); + virtual void setText(const QByteArray & szText); + virtual void getText(QString & szText); + virtual void getText(QByteArray & szText); + virtual void setFindText(const QString & szText); + virtual void setEnabled(bool bEnabled); + virtual void setReadOnly(bool bReadOnly); + void setUnHighlightedText(const QString & szText); + + + virtual void setFocus(); + virtual bool isModified(); + virtual void setModified(bool); + + int getCursor(){return m_pEditor->textCursor().position();}; + void setCursorPosition(int iPos); + int cursor(){ return m_lastCursorPos; }; + QLineEdit * findLineEdit(){ return m_pFindLineEdit; }; +protected: + virtual void focusInEvent(QFocusEvent * e); + void loadOptions(); + void saveOptions(); +protected slots: + void saveToFile(); + void loadFromFile(); + void configureColors(); + void updateRowColLabel(); + void slotFind(); + void slotReplaceAll(const QString & szToReplace, const QString & szReplaceWith); + void slotInitFind(); + void slotNextFind(const QString &); + void optionsDialogFinished(int iResult); +signals: + void find(const QString &); + void replaceAll(const QString & szToReplace, const QString & szReplaceWith); + void initFind(); + void nextFind(const QString & szText); +}; + +class ScriptEditorReplaceDialog: public QDialog +{ + Q_OBJECT +public: + ScriptEditorReplaceDialog(QWidget * parent = 0, const QString & szName = QString()); + ~ScriptEditorReplaceDialog(); +public: + QLineEdit * m_pFindLineEdit; + QLineEdit * m_pReplaceLineEdit; +protected: + QPushButton * m_pReplaceButton; + QCheckBox * m_pCheckReplaceAll; + QWidget * m_pParent; +protected slots: + void textChanged(const QString &); + void slotReplace(); + void slotNextFind(); +signals: + void replaceAll(const QString &, const QString &); + void initFind(); + void nextFind(const QString &); +}; + +#endif // _SCRIPTEDITOR_H_ diff --git a/src/modules/editor/libkvieditor.cpp b/src/modules/editor/libkvieditor.cpp index cd65b52d7..6ed7b541a 100644 --- a/src/modules/editor/libkvieditor.cpp +++ b/src/modules/editor/libkvieditor.cpp @@ -22,7 +22,7 @@ // //============================================================================= -#include "scripteditor.h" +#include "ScriptEditorImplementation.h" #include "KviModule.h" #include "KviWindow.h" @@ -30,11 +30,11 @@ KviModule * g_pEditorModulePointer = 0; -KviPointerList * g_pScriptEditorWindowList = 0; +KviPointerList * g_pScriptEditorWindowList = 0; static bool editor_module_init(KviModule * m) { - g_pScriptEditorWindowList = new KviPointerList; + g_pScriptEditorWindowList = new KviPointerList; g_pScriptEditorWindowList->setAutoDelete(false); g_pEditorModulePointer = m; @@ -97,10 +97,10 @@ KVIRC_MODULE( KVIMODULEEXPORTFUNC KviScriptEditor * editor_module_createScriptEditor(QWidget * par) { - return new KviScriptEditorImplementation(par); + return new ScriptEditorImplementation(par); } KVIMODULEEXPORTFUNC void editor_module_destroyScriptEditor(KviScriptEditor * e) { - delete ((KviScriptEditorImplementation *)e); + delete ((ScriptEditorImplementation *)e); } diff --git a/src/modules/editor/scripteditor.cpp b/src/modules/editor/scripteditor.cpp deleted file mode 100644 index f38f9d33c..000000000 --- a/src/modules/editor/scripteditor.cpp +++ /dev/null @@ -1,1137 +0,0 @@ -//============================================================================= -// -// File : scripteditor.cpp -// Creation date : Sun Mar 28 1999 16:11:48 CEST by Szymon Stefanek -// -// This file is part of the KVIrc IRC client distribution -// Copyright (C) 1999 Szymon Stefanek -// Copyright (C) 2005 Tonino Imbesi -// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "scripteditor.h" - -#include "KviFileUtils.h" -#include "kvi_fileextensions.h" -#include "KviLocale.h" -#include "KviFileDialog.h" -#include "KviQString.h" -#include "KviConfigurationFile.h" -#include "KviModule.h" -#include "KviPointerList.h" -#include "KviApplication.h" -#include "KviConsoleWindow.h" -#include "KviWindow.h" -#include "KviIconManager.h" -#include "KviKvsKernel.h" -#include "KviModuleManager.h" -#include "KviConfigurationFile.h" -#include "KviTalVBox.h" -#include "KviTalHBox.h" -#include "KviTalGroupBox.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern KVIRC_API KviModuleManager * g_pModuleManager; -extern KviPointerList * g_pScriptEditorWindowList; -extern KviModule * g_pEditorModulePointer; - -static QColor g_clrBackground(0,0,0); -static QColor g_clrNormalText(100,255,0); -static QColor g_clrBracket(255,0,0); -static QColor g_clrComment(0,120,0); -static QColor g_clrFunction(255,255,0); -static QColor g_clrKeyword(120,120,150); -static QColor g_clrVariable(200,200,200); -static QColor g_clrPunctuation(180,180,0); -static QColor g_clrFind(255,0,0); - -#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - #define KVI_SCRIPTEDITOR_DEFAULT_FONT "Courier New" -#else - #define KVI_SCRIPTEDITOR_DEFAULT_FONT "Monospace" -#endif -static QFont g_fntNormal(KVI_SCRIPTEDITOR_DEFAULT_FONT,8); - -static bool bSemaphore=false; -static bool bCompleterReady=false; - - -KviScriptEditorWidget::KviScriptEditorWidget(QWidget * pParent) -: QTextEdit(pParent) -{ - m_pSyntaxHighlighter=0; - setTabStopWidth(48); - setAcceptRichText(false); - setWordWrapMode(QTextOption::NoWrap); - m_pParent = pParent; - m_szHelp = "Nothing"; - updateOptions(); - m_szFind = ""; - m_pCompleter = 0; - QStringList szListFunctionsCommands; - QString tmp("kvscompleter.idx"); - iModulesCount=0; - iIndex=0; - QString szPath; - g_pApp->getLocalKvircDirectory(szPath,KviApplication::ConfigPlugins,tmp); - - if(!KviFileUtils::fileExists(szPath)) - { - if (!bSemaphore){ - bSemaphore=true; - m_pStartTimer = new QTimer(); - m_pStartTimer->setInterval(1000); - connect(m_pStartTimer,SIGNAL(timeout()),this,SLOT(asyncCompleterCreation())); - m_pStartTimer->start(500); - } - else{ - m_pStartTimer = new QTimer(); - m_pStartTimer->setInterval(2000); - connect(m_pStartTimer,SIGNAL(timeout()),this,SLOT(checkReadyCompleter())); - m_pStartTimer->start(1000); - } - } else loadCompleterFromFile(); -} - -KviScriptEditorWidget::~KviScriptEditorWidget() -{ - if(m_pCompleter) - delete m_pCompleter; - disableSyntaxHighlighter(); -} - -void KviScriptEditorWidget::checkReadyCompleter() -{ - if(bCompleterReady) - { - m_pStartTimer->stop(); - delete m_pStartTimer; - m_pStartTimer=0; - loadCompleterFromFile(); - } -} - -void KviScriptEditorWidget::asyncCompleterCreation() -{ - //static int iIndex = 0; - //static int iModulesCount = 0; - if(!iIndex) - { - m_pListCompletition = new QStringList(); - QString szPath; - - g_pApp->getGlobalKvircDirectory(szPath,KviApplication::Modules); - - QDir d(szPath); - -#if defined(COMPILE_ON_WINDOWS) - d.setNameFilters(QStringList("kvi*.dll")); -#elif defined(COMPILE_ON_MINGW) - d.setNameFilters(QStringList("libkvi*.dll")); -#else - d.setNameFilters(QStringList("libkvi*.so")); -#endif - m_pListModulesNames = new QStringList(d.entryList(QDir::Files | QDir::Readable)); - iModulesCount = m_pListModulesNames->count(); - } - QString szModuleName = m_pListModulesNames->at(iIndex); - iIndex++; - -#if defined(COMPILE_ON_WINDOWS) - szModuleName=szModuleName.replace("kvi",""); - szModuleName=szModuleName.replace(".dll",""); -#elif defined(COMPILE_ON_MINGW) - szModuleName=szModuleName.replace("libkvi",""); - szModuleName=szModuleName.replace(".dll",""); -#else - szModuleName=szModuleName.replace("libkvi",""); - szModuleName=szModuleName.replace(".so",""); -#endif - - KviModule * pModule = g_pModuleManager->getModule(szModuleName); - if(pModule) - { - pModule->getAllFunctionsCommandsModule(m_pListCompletition,szModuleName); - } - - if(iIndex == iModulesCount) - { - m_pStartTimer->stop(); - m_pStartTimer->deleteLater(); - m_pStartTimer = 0; - QString szTmp("kvscompleter.idx"); - QString szPath; - g_pApp->getLocalKvircDirectory(szPath,KviApplication::ConfigPlugins,szTmp); - KviKvsKernel::instance()->getAllFunctionsCommandsCore(m_pListCompletition); - QString szBuffer = m_pListCompletition->join(","); - QFile f(szPath); - f.open(QIODevice::WriteOnly); - f.write(szBuffer.toUtf8()); - f.close(); - createCompleter(*m_pListCompletition); - iIndex = 0; - iModulesCount = 0; - bCompleterReady=true; - delete m_pListCompletition; - delete m_pListModulesNames; - } -} - -void KviScriptEditorWidget::loadCompleterFromFile() -{ - QStringList szListFunctionsCommand; - QString szTmp("kvscompleter.idx"); - QString szPath; - g_pApp->getLocalKvircDirectory(szPath,KviApplication::ConfigPlugins,szTmp); - QString szBuffer; - QFile f(szPath); - f.open(QIODevice::ReadOnly); - szBuffer = f.readAll(); - f.close(); - szListFunctionsCommand = szBuffer.split(','); - createCompleter(szListFunctionsCommand); -} - -void KviScriptEditorWidget::createCompleter(QStringList & list) -{ - m_pCompleter = new QCompleter(list); - m_pCompleter->setCaseSensitivity(Qt::CaseInsensitive); - m_pCompleter->setWrapAround(false); - m_pCompleter->setWidget(this); - m_pCompleter->setModelSorting(QCompleter::CaseSensitivelySortedModel); - m_pCompleter->setCompletionMode(QCompleter::PopupCompletion); - m_pCompleter->setCaseSensitivity(Qt::CaseInsensitive); - QObject::connect(m_pCompleter, SIGNAL(activated(const QString &)),this, SLOT(insertCompletion(const QString &))); -} - -void KviScriptEditorWidget::insertCompletion(const QString & szCompletion) -{ - QTextCursor tc = textCursor(); - int iExtra = szCompletion.length() - m_pCompleter->completionPrefix().length(); - - tc.movePosition(QTextCursor::Left); - tc.movePosition(QTextCursor::EndOfWord); - - QString szTmp = szCompletion.right(iExtra); - if(szCompletion.left(1)=="$") - szTmp.append("("); - else - szTmp.append(" "); - - tc.insertText(szTmp); - setTextCursor(tc); -} - -void KviScriptEditorWidget::contextMenuEvent(QContextMenuEvent * e) -{ - QMenu * pMenu = createStandardContextMenu(); - pMenu->addAction(__tr2qs_ctx("Context sensitive help","editor"),this,SLOT(slotHelp()),Qt::CTRL+Qt::Key_H); - pMenu->addAction(__tr2qs_ctx("&Replace","editor"),this,SLOT(slotReplace()),Qt::CTRL+Qt::Key_R); - pMenu->exec(e->globalPos()); - delete pMenu; -} - -void KviScriptEditorWidget::slotFind() -{ - m_szFind = ((KviScriptEditorImplementation*)m_pParent)->findLineEdit()->text(); - setText(toPlainText()); -} - -void KviScriptEditorWidget::slotReplace() -{ - KviScriptEditorReplaceDialog * pDialog = new KviScriptEditorReplaceDialog(this,__tr2qs_ctx("Find & Replace","editor")); - connect(pDialog,SIGNAL(replaceAll(const QString &,const QString &)),m_pParent,SLOT(slotReplaceAll(const QString &,const QString &))); - connect(pDialog,SIGNAL(initFind()),m_pParent,SLOT(slotInitFind())); - connect(pDialog,SIGNAL(nextFind(const QString &)),m_pParent,SLOT(slotNextFind(const QString &))); - - if(pDialog->exec()){}; -} - -void KviScriptEditorWidget::slotHelp() -{ - contextSensitiveHelp(); -} -void KviScriptEditorWidget::enableSyntaxHighlighter() -{ - // we currently delete and re-create the m_pSyntaxHighlighter - // as a trick to ensure proper re-highlightning to occur - if (!m_pSyntaxHighlighter) - m_pSyntaxHighlighter = new KviScriptEditorSyntaxHighlighter(this); -} -void KviScriptEditorWidget::disableSyntaxHighlighter() -{ - if (m_pSyntaxHighlighter) delete m_pSyntaxHighlighter; - m_pSyntaxHighlighter = 0; -} - -void KviScriptEditorWidget::updateOptions() -{ - QPalette p = palette(); - p.setColor(QPalette::Base,g_clrBackground); - p.setColor(QPalette::Text,g_clrNormalText); - setPalette(p); - setFont(g_fntNormal); - setTextColor(g_clrNormalText); - disableSyntaxHighlighter(); - enableSyntaxHighlighter(); - - p = ((KviScriptEditorImplementation*)m_pParent)->findLineEdit()->palette(); - p.setColor(foregroundRole(),g_clrFind); - ((KviScriptEditorImplementation*)m_pParent)->findLineEdit()->setPalette(p); -} - -void KviScriptEditorWidget::keyPressEvent(QKeyEvent * e) -{ - if(m_pCompleter && m_pCompleter->popup()->isVisible()) - { - switch(e->key()) - { - case Qt::Key_Enter: - case Qt::Key_Return: - case Qt::Key_Escape: - case Qt::Key_Tab: - case Qt::Key_Backtab: - e->ignore(); - return; - default: - break; - } - } - - if(e->modifiers() == Qt::ControlModifier) - { - switch(e->key()) - { - case Qt::Key_B: - insertPlainText("$b"); - return; - case Qt::Key_K: - insertPlainText("$k"); - return; - case Qt::Key_O: - insertPlainText("$o"); - return; - case Qt::Key_U: - insertPlainText("$u"); - return; - case Qt::Key_Enter: - case Qt::Key_Return: - case Qt::Key_PageUp: - e->ignore(); // allow the parent to process it - return; - break; - } - } -// Adapted from QT4 QCompleter example - bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E); // CTRL+E - if (!m_pCompleter || !isShortcut) // don't process the shortcut when we have a completer - QTextEdit::keyPressEvent(e); - const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier); - if (!m_pCompleter || (ctrlOrShift && e->text().isEmpty())) - return; - static QString eow("~!@#$%^&*()_+{}|:\"<>?,/;'[]\\-="); // end of word - bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift; - QString completionPrefix = textUnderCursor(); - if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 3 || eow.contains(e->text().right(1)))) - { - m_pCompleter->popup()->hide(); - return; - } - if (completionPrefix != m_pCompleter->completionPrefix()) - { - m_pCompleter->setCompletionPrefix(completionPrefix); - m_pCompleter->popup()->setCurrentIndex(m_pCompleter->completionModel()->index(0, 0)); - } - QRect cr = cursorRect(); - cr.setWidth(m_pCompleter->popup()->sizeHintForColumn(0)+ m_pCompleter->popup()->verticalScrollBar()->sizeHint().width()); - m_pCompleter->complete(cr); -} - -QString KviScriptEditorWidget::textUnderCursor() const -{ - QString szWord; - QTextCursor tc = textCursor(); - if(tc.atBlockStart()) - return QString(); - tc.clearSelection(); - tc.movePosition(QTextCursor::StartOfWord,QTextCursor::KeepAnchor); - if(tc.atBlockStart()) - { - szWord.append(tc.selectedText()); - tc.movePosition(QTextCursor::EndOfWord,QTextCursor::KeepAnchor); - szWord.append(tc.selectedText()); - if(tc.atBlockEnd()){ - return szWord; - } - tc.movePosition(QTextCursor::NextCharacter,QTextCursor::KeepAnchor); - szWord.append(tc.selectedText()); - if(szWord.right(1)!=".") - szWord.chop(1); - return szWord; - } - - tc.movePosition(QTextCursor::PreviousCharacter,QTextCursor::KeepAnchor); - szWord=tc.selectedText(); - if(szWord.left(1)==".") - { - tc.movePosition(QTextCursor::StartOfWord); - tc.movePosition(QTextCursor::PreviousCharacter); - tc.movePosition(QTextCursor::PreviousWord); - tc.movePosition(QTextCursor::EndOfWord,QTextCursor::KeepAnchor,1); - szWord.prepend(tc.selectedText()); - } else szWord.remove(0,1); - return szWord; -} -/* -void KviScriptEditorWidget::mouseReleaseEvent(QMouseEvent * e) -{ - - return; - QRect r = cursorRect(); - QTextCursor cur = cursorForPosition(e->pos()); - // cur.select( - - - //completelistbox->hide(); - if (e->button() == Qt::RightButton) - { - QString szBuffer; - /\* - int iPara = paragraphAt(e->pos()); - int iIndex=charAt(e->pos(),&iPara); - szBuffer = this->text(iPara); - getWordOnCursor(szBuffer,iIndex); - *\/ - QRect r = cursorRect(); - QTextCursor cur = cursorForPosition(e->pos()); - cur.select(QTextCursor::WordUnderCursor); - szBuffer = cur.selectedText(); - QString szTmp = szBuffer; - KviPointerList * pList; - if(szTmp.left(1) == "$") - { - szTmp.remove(0,1); - pList = KviKvsKernel::instance()->completeCommandAllocateResult(szTmp); - if (pList->count() != 1) - szBuffer = ""; - else - szBuffer = *(pList->at(0)); - } else { - pList = KviKvsKernel::instance()->completeCommandAllocateResult(szTmp); - if (pList->count() != 1) - szBuffer = ""; - else - szBuffer = *(pList->at(0)); - } - - for (unsigned int i=0; i < pList->count(); i++) - QString str = *(pList->at(i)); - - KviKvsKernel::instance()->freeCompletionResult(pList); - m_szHelp = szBuffer; - } - - QTextEdit::mouseReleaseEvent(e); -} -*/ -bool KviScriptEditorWidget::contextSensitiveHelp() const -{ - /* - QString szBuffer; - int iPara, iIndex; - getCursorPosition(&iPara,&iIndex); - szBuffer = text(iPara); - getWordOnCursor(szBuffer,iIndex); - */ - - QRect r = cursorRect(); - QTextCursor cur = cursorForPosition(QPoint(r.x(),r.y())); - cur.select(QTextCursor::WordUnderCursor); - QString szText = cur.selectedText(); - QString szTmp = szText; - /* - KviPointerList * pList; - if(szTmp.left(1) == "$") - { - szTmp.remove(0,1); - pList = g_pUserParser->completeFunctionAllocateResult(szTmp); - } else { - pList = g_pUserParser->completeCommandAllocateResult(szTmp); - } - qDebug("command or func %s",szTmp.toUtf8().data()); - - bool bOk = false; - if(pList) - { - for(QString * s = pList->first(); s; s = pList->next()) - { - if(KviQString::equalCI(*s,szBuffer)) - { - pList->last(); - bOk = true; - } - } - } - - g_pUserParser->freeCompletionResult(pList); - if(!bOk)return false; - - QString szParse; - KviQString::sprintf(szParse,"timer -s (help,0){ help -s %Q; }",&szBuffer); - qDebug("parsing %s",szParse.toLatin1()); - KviKvsScript::run(szParse,(KviWindow*)g_pApp->activeConsole()); - */ - - return true; -} - -KviScriptEditorWidgetColorOptions::KviScriptEditorWidgetColorOptions(QWidget * pParent) -: QDialog(pParent) -{ - m_pSelectorInterfaceList = new KviPointerList; - m_pSelectorInterfaceList->setAutoDelete(false); - setWindowTitle(__tr2qs_ctx("Preferences","editor")); - QGridLayout * g = new QGridLayout(this); - KviTalVBox * box = new KviTalVBox(this); - g->addWidget(box,0,0); - box->setMargin(0); - box->setSpacing(0); - KviFontSelector * f = new KviFontSelector(box,__tr2qs_ctx("Font:","editor"),&g_fntNormal,true); - m_pSelectorInterfaceList->append(f); - KviTalGroupBox * gbox = new KviTalGroupBox(Qt::Horizontal,__tr2qs_ctx("Colors","editor"),box); - gbox->setInsideSpacing(0); - - addColorSelector(gbox,__tr2qs_ctx("Background:","editor"),&g_clrBackground,true); - addColorSelector(gbox,__tr2qs_ctx("Normal text:","editor"),&g_clrNormalText,true); - addColorSelector(gbox,__tr2qs_ctx("Brackets:","editor"),&g_clrBracket,true); - addColorSelector(gbox,__tr2qs_ctx("Comments:","editor"),&g_clrComment,true); - addColorSelector(gbox,__tr2qs_ctx("Functions:","editor"),&g_clrFunction,true); - addColorSelector(gbox,__tr2qs_ctx("Keywords:","editor"),&g_clrKeyword,true); - addColorSelector(gbox,__tr2qs_ctx("Variables:","editor"),&g_clrVariable,true); - addColorSelector(gbox,__tr2qs_ctx("Punctuation:","editor"),&g_clrPunctuation,true); - addColorSelector(gbox,__tr2qs_ctx("Find:","editor"),&g_clrFind,true); - - KviTalHBox * hbox = new KviTalHBox(box); - - QPushButton * b = new QPushButton(__tr2qs_ctx("OK","editor"),hbox); - b->setDefault(true); - connect(b,SIGNAL(clicked()),this,SLOT(okClicked())); - - b = new QPushButton(__tr2qs_ctx("Cancel","editor"),hbox); - connect(b,SIGNAL(clicked()),this,SLOT(reject())); -} - -KviScriptEditorWidgetColorOptions::~KviScriptEditorWidgetColorOptions() -{ - delete m_pSelectorInterfaceList; -} - -KviColorSelector * KviScriptEditorWidgetColorOptions::addColorSelector(QWidget * pParent,const QString & txt,QColor * pOption,bool bEnabled) -{ - KviColorSelector * s = new KviColorSelector(pParent,txt,pOption,bEnabled); - m_pSelectorInterfaceList->append(s); - return s; -} - -void KviScriptEditorWidgetColorOptions::okClicked() -{ - for(KviSelectorInterface * i = m_pSelectorInterfaceList->first();i;i = m_pSelectorInterfaceList->next()) - { - i->commit(); - } - accept(); -} - - -KviScriptEditorSyntaxHighlighter::KviScriptEditorSyntaxHighlighter(KviScriptEditorWidget * pWidget) -: QSyntaxHighlighter(pWidget),m_pTextEdit(pWidget) -{ - // code adpated from QT4 example - - // FIX-ME: "function ..." - "function internal ..." - // FIX-ME: "@$" - // FIX-ME: "\" escape char - updateSyntaxtTextFormat(); - - KviScriptHighlightingRule rule; - - rule.pattern=QRegExp("([=()[\\]!\"?<>;:.,+-])+"); - rule.format=punctuationFormat; - highlightingRules.append(rule); - - rule.pattern=QRegExp("[{};](|[a-zA-Z]|[a-zA-Z]+[a-zA-Z0-9_\\.:]*)"); - rule.format=keywordFormat; - highlightingRules.append(rule); - - - rule.pattern=QRegExp("[$](|[a-zA-Z0-9]+[a-zA-Z0-9_\\.:]*)"); - rule.format=functionFormat; - highlightingRules.append(rule); - - rule.pattern=QRegExp("[%](|[a-zA-Z]|[a-zA-Z]+[a-zA-Z0-9_\\.]*)"); - rule.format=variableFormat; - highlightingRules.append(rule); - - rule.pattern=QRegExp("([{}])+"); - rule.format=bracketFormat; - highlightingRules.append(rule); -} - -KviScriptEditorSyntaxHighlighter::~KviScriptEditorSyntaxHighlighter() -{ -} - -void KviScriptEditorSyntaxHighlighter::updateSyntaxtTextFormat() -{ - punctuationFormat.setForeground(g_clrPunctuation); - keywordFormat.setForeground(g_clrKeyword); - functionFormat.setForeground(g_clrFunction); - variableFormat.setForeground(g_clrVariable); - bracketFormat.setForeground(g_clrBracket); - commentFormat.setForeground(g_clrComment); - findFormat.setForeground(g_clrFind); -} - -#define SKIP_SPACES \ - while(iIndexStart < szText.size()) \ - { \ - if(szText.at(iIndexStart).unicode()=='\t' || szText.at(iIndexStart).unicode()==' ') \ - { \ - iIndexStart++; \ - } else { \ - break; \ - } \ - } \ - -void KviScriptEditorSyntaxHighlighter::highlightBlock(const QString & szText) -{ - if(szText.isEmpty()) - { - setCurrentBlockState(previousBlockState()); - return; - } - - int iIndexStart=0; - setCurrentBlockState(0); - - if(previousBlockState() == 1) - { - // inside a multiline comment - int iCommentEnd = szText.indexOf("*/"); - if(iCommentEnd < 0) - { - // not found: comment until the end of the block - setCurrentBlockState(1); - setFormat(iIndexStart,szText.length(),commentFormat); - return; - } - // skip 2 chars - iCommentEnd+=2; - // end of comment found - setFormat(iIndexStart,iCommentEnd - iIndexStart,commentFormat); - iIndexStart = iCommentEnd; - } - - SKIP_SPACES - - if (iIndexStart == szText.size()) - return; - - // check 'commands' and comments - int iCommandStart=iIndexStart; - if (szText.at(iIndexStart).unicode()!='$' && szText.at(iIndexStart).unicode()!='{' && szText.at(iIndexStart).unicode()!='}' && szText.at(iIndexStart).unicode()!='%') - { - switch(szText.at(iIndexStart).unicode()) - { - case '#': - // single line comment, bash style - while(iIndexStart= 0) - { - int length = expression.matchedLength(); - setFormat(index, length, rule.format); - index = szText.indexOf(expression, index + length); - } - } - - // 'found matches' highlighting - KviScriptEditorWidget * pEditor = ((KviScriptEditorWidget *)textEdit()); - QString szFind = pEditor->m_szFind; - if (!szFind.isEmpty()) - { - index = szText.indexOf(szFind,0,Qt::CaseInsensitive); - int length=szFind.length(); - while (index >= 0) - { - setFormat(index, length, findFormat); - index = szText.indexOf(szFind,index + length,Qt::CaseInsensitive); - } - } -} - - -KviScriptEditorImplementation::KviScriptEditorImplementation(QWidget * par) -:KviScriptEditor(par) -{ - m_pOptionsDialog=0; - if(g_pScriptEditorWindowList->isEmpty())loadOptions(); - g_pScriptEditorWindowList->append(this); - m_lastCursorPos = 0; - QGridLayout * g = new QGridLayout(this); - - m_pFindLineEdit = new QLineEdit(" ",this); - m_pFindLineEdit->setText(""); - - QPalette p = m_pFindLineEdit->palette(); - p.setColor(foregroundRole(), g_clrFind); - m_pFindLineEdit->setPalette(p); - - m_pEditor = new KviScriptEditorWidget(this); - - g->addWidget(m_pEditor, 0, 0, 1,4); - g->setRowStretch(0,1); - - QToolButton * b = new QToolButton(this); - b->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_OPTIONS))); - - b->setObjectName("ToolButtonEditor"); - b->setMinimumWidth(24); - g->addWidget(b,1,0); - - KviTalPopupMenu * pop = new KviTalPopupMenu(b); - pop->insertItem(__tr2qs_ctx("&Open...","editor"),this,SLOT(loadFromFile())); - pop->insertItem(__tr2qs_ctx("&Save As...","editor"),this,SLOT(saveToFile())); - pop->insertSeparator(); - pop->insertItem(__tr2qs_ctx("&Configure Editor...","editor"),this,SLOT(configureColors())); - b->setMenu(pop); - b->setPopupMode(QToolButton::InstantPopup); - - g->setColumnStretch(1,1); - g->setColumnStretch(2,10); - g->addWidget(m_pFindLineEdit,1,2); - - QLabel * pLab = new QLabel(this); - pLab->setText(__tr2qs_ctx("Find","editor")); - g->addWidget(pLab,1,1); - - m_pRowColLabel = new QLabel("0",this); - m_pRowColLabel->setFrameStyle(QFrame::Sunken | QFrame::Panel); - m_pRowColLabel->setMinimumWidth(80); - g->addWidget(m_pRowColLabel,1,3); - - connect(m_pFindLineEdit,SIGNAL(returnPressed()),m_pEditor,SLOT(slotFind())); - connect(m_pFindLineEdit,SIGNAL(returnPressed()),this,SLOT(slotFind())); - connect(m_pEditor,SIGNAL(cursorPositionChanged()),this,SLOT(updateRowColLabel())); - connect(m_pEditor,SIGNAL(selectionChanged()),this,SLOT(updateRowColLabel())); - m_lastCursorPos = 0; -} - -KviScriptEditorImplementation::~KviScriptEditorImplementation() -{ - if(m_pOptionsDialog) - { - m_pOptionsDialog->deleteLater(); - m_pOptionsDialog=0; - } - g_pScriptEditorWindowList->removeRef(this); - if(g_pScriptEditorWindowList->isEmpty()) - saveOptions(); -} - -void KviScriptEditorImplementation::loadOptions() -{ - QString szTmp; - g_pEditorModulePointer->getDefaultConfigFileName(szTmp); - - KviConfigurationFile cfg(szTmp,KviConfigurationFile::Read); - g_clrBackground = cfg.readColorEntry("Background",QColor(0,0,0));; - g_clrNormalText = cfg.readColorEntry("NormalText",QColor(100,255,0)); - g_clrBracket = cfg.readColorEntry("Bracket",QColor(255,0,0)); - g_clrComment = cfg.readColorEntry("Comment",QColor(0,120,0)); - g_clrFunction = cfg.readColorEntry("Function",QColor(255,255,0)); - g_clrKeyword = cfg.readColorEntry("Keyword",QColor(120,120,150)); - g_clrVariable = cfg.readColorEntry("Variable",QColor(200,200,200)); - g_clrPunctuation = cfg.readColorEntry("Punctuation",QColor(180,180,0)); - g_clrFind = cfg.readColorEntry("Find",QColor(255,0,0)); - g_fntNormal = cfg.readFontEntry("Font",QFont(KVI_SCRIPTEDITOR_DEFAULT_FONT,8)); -} - -bool KviScriptEditorImplementation::isModified() -{ - return m_pEditor->document()->isModified(); -} -void KviScriptEditorImplementation::setModified(bool bModified) -{ - return m_pEditor->document()->setModified(bModified); -} -void KviScriptEditorImplementation::slotFind() -{ - emit find(m_pFindLineEdit->text()); -} - -void KviScriptEditorImplementation::slotNextFind(const QString &) //szText -{ -// emit nextFind(const QString & szText); -} - -void KviScriptEditorImplementation::slotInitFind() -{ - emit initFind(); -} - -void KviScriptEditorImplementation::slotReplaceAll(const QString & szToReplace, const QString & szReplaceWith) -{ - emit replaceAll(szToReplace,szReplaceWith); -} - -void KviScriptEditorImplementation::saveOptions() -{ - QString szTmp; - g_pEditorModulePointer->getDefaultConfigFileName(szTmp); - - KviConfigurationFile cfg(szTmp,KviConfigurationFile::Write); - cfg.writeEntry("Background",g_clrBackground);; - cfg.writeEntry("NormalText",g_clrNormalText); - cfg.writeEntry("Bracket",g_clrBracket); - cfg.writeEntry("Comment",g_clrComment); - cfg.writeEntry("Function",g_clrFunction); - cfg.writeEntry("Keyword",g_clrKeyword); - cfg.writeEntry("Variable",g_clrVariable); - cfg.writeEntry("Punctuation",g_clrPunctuation); - cfg.writeEntry("Find",g_clrFind); - cfg.writeEntry("Font",g_fntNormal); -} - -void KviScriptEditorImplementation::setFocus() -{ - m_pEditor->setFocus(); -} - -void KviScriptEditorImplementation::focusInEvent(QFocusEvent *) -{ - m_pEditor->setFocus(); -} - -void KviScriptEditorImplementation::setEnabled(bool bEnabled) -{ - QWidget::setEnabled(bEnabled); - m_pEditor->setEnabled(bEnabled); - m_pRowColLabel->setEnabled(bEnabled); -} - -void KviScriptEditorImplementation::saveToFile() -{ - QString szFileName; - if(KviFileDialog::askForSaveFileName(szFileName, - __tr2qs_ctx("Choose a Filename - KVIrc","editor"), - QString::null, - QString::null,false,true,true)) - { - QString szBuffer = m_pEditor->toPlainText(); - - //if(tmp.isEmpty())tmp = ""; - //KviCString buffer = tmp.toUtf8().data(); - if(!KviFileUtils::writeFile(szFileName,szBuffer)) - { - QString szTmp; - QMessageBox::warning(this, - __tr2qs_ctx("Save Failed - KVIrc","editor"), - KviQString::sprintf(szTmp,__tr2qs_ctx("Can't open the file %s for writing.","editor"),&szFileName)); - } - } -} - -void KviScriptEditorImplementation::setText(const char * txt) -{ - setText(QByteArray(txt)); -} -void KviScriptEditorImplementation::setUnHighlightedText(const QString & szText) -{ - m_pEditor->disableSyntaxHighlighter(); - m_pEditor->setText(szText); -} -void KviScriptEditorImplementation::setText(const QByteArray & szText) -{ - m_pEditor->setPlainText(szText.data()); - m_pEditor->document()->setModified(false); - updateRowColLabel(); -} -void KviScriptEditorImplementation::setReadOnly(bool bReadOnly) -{ - m_pEditor->setReadOnly(bReadOnly); -} -void KviScriptEditorImplementation::getText(QByteArray & szText) -{ - szText = m_pEditor->toPlainText().toUtf8(); -} - -void KviScriptEditorImplementation::setText(const QString & szText) -{ - m_pEditor->enableSyntaxHighlighter(); - m_pEditor->setPlainText(szText); - QTextCursor cur=m_pEditor->textCursor(); - cur.movePosition(QTextCursor::End); - m_pEditor->setTextCursor(cur); - m_pEditor->document()->setModified(false); - updateRowColLabel(); -} - -void KviScriptEditorImplementation::getText(QString & szText) -{ - szText = m_pEditor->toPlainText(); -} - -void KviScriptEditorImplementation::setFindText(const QString & szText) -{ - m_pFindLineEdit->setText(szText); - m_pEditor->slotFind(); -} - -void KviScriptEditorImplementation::updateRowColLabel() -{ - if(m_lastCursorPos==m_pEditor->textCursor().position()) - return; - int iRow = m_pEditor->textCursor().blockNumber(); - int iCol = m_pEditor->textCursor().columnNumber(); - QString szTmp; - KviQString::sprintf(szTmp,__tr2qs_ctx("Row: %d Col: %d","editor"),iRow,iCol); - m_pRowColLabel->setText(szTmp); - m_lastCursorPos = m_pEditor->textCursor().position(); -} - -void KviScriptEditorImplementation::setCursorPosition(int iPos) -{ - QTextCursor cur = m_pEditor->textCursor(); - cur.setPosition(iPos); - m_pEditor->setTextCursor(cur); - updateRowColLabel(); -} - -void KviScriptEditorImplementation::loadFromFile() -{ - QString szFileName; - if(KviFileDialog::askForOpenFileName(szFileName, - __tr2qs_ctx("Load Script File - KVIrc","editor"), - QString::null,KVI_FILTER_SCRIPT,false,true)) - { - QString szBuffer; - if(KviFileUtils::loadFile(szFileName,szBuffer)) - { - m_pEditor->setPlainText(szBuffer); - setCursorPosition(0); - //m_pEditor->moveCursor(QTextEdit::MoveEnd,false); - //updateRowColLabel(); - } else { - QString szTmp; - QMessageBox::warning(this, - __tr2qs_ctx("Open Failed - KVIrc","editor"), - KviQString::sprintf(szTmp,__tr2qs_ctx("Can't open the file %s for reading.","editor"),&szFileName)); - } - } -} - -void KviScriptEditorImplementation::configureColors() -{ - if(!m_pOptionsDialog) - { - m_pOptionsDialog = new KviScriptEditorWidgetColorOptions(this); - connect(m_pOptionsDialog,SIGNAL(finished(int)),this,SLOT(optionsDialogFinished(int))); - } - m_pOptionsDialog->show(); -} - -void KviScriptEditorImplementation::optionsDialogFinished(int iResult) -{ - if(iResult == QDialog::Accepted) - { - m_pEditor->updateOptions(); - saveOptions(); - } -} - -KviScriptEditorReplaceDialog::KviScriptEditorReplaceDialog(QWidget * pParent, const QString & szName) -: QDialog(pParent) -{ - setObjectName(szName); - - m_pParent = pParent; - emit initFind(); - QPalette p = palette(); - p.setColor(foregroundRole(),QColor( 0, 0, 0 )); - p.setColor(backgroundRole(),QColor( 236, 233, 216 )); - setPalette(p); - - QGridLayout * pLayout = new QGridLayout(this); - pLayout->setObjectName("replace layout"); - - QLabel * m_pFindLabel = new QLabel(this); - m_pFindLabel->setObjectName("findlabel"); - m_pFindLabel->setText(__tr2qs_ctx("Word to Find","editor")); - pLayout->addWidget(m_pFindLabel,0,0); - - m_pFindLineEdit = new QLineEdit(this); - m_pFindLineEdit->setObjectName("findlineedit"); - pLayout->addWidget(m_pFindLineEdit,0,1); - - QLabel * m_pReplaceLabel = new QLabel(this); - m_pReplaceLabel->setObjectName("replacelabel"); - m_pReplaceLabel->setText(__tr2qs_ctx("Replace with","editor")); - pLayout->addWidget(m_pReplaceLabel,1,0); - - m_pReplaceLineEdit = new QLineEdit(this); - m_pReplaceLineEdit->setObjectName("replacelineedit"); - pLayout->addWidget(m_pReplaceLineEdit,1,1); - - - m_pFindLineEdit->setFocus(); - - m_pCheckReplaceAll = new QCheckBox(this); - m_pCheckReplaceAll->setObjectName("replaceAll"); - m_pCheckReplaceAll->setText(__tr2qs_ctx("&Replace in all editor's items","editor")); - pLayout->addWidget(m_pCheckReplaceAll,2,0); - - QPushButton * pCancelButton = new QPushButton(this); - pCancelButton->setObjectName("cancelButton"); - pCancelButton->setText(__tr2qs_ctx("&Cancel","editor")); - pLayout->addWidget(pCancelButton,3,0); - - m_pReplaceButton = new QPushButton(this); - m_pReplaceButton->setObjectName("replacebutton"); - m_pReplaceButton->setText(__tr2qs_ctx("&Replace","editor")); - m_pReplaceButton->setEnabled(false); - pLayout->addWidget(m_pReplaceButton,3,1); - - setLayout(pLayout); - - // signals and slots connections - connect(m_pReplaceButton, SIGNAL(clicked()), this, SLOT(slotReplace())); - connect(pCancelButton, SIGNAL(clicked()), this, SLOT(reject())); - connect(m_pFindLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged(const QString &))); -} - -KviScriptEditorReplaceDialog::~KviScriptEditorReplaceDialog() -{ -} - -void KviScriptEditorReplaceDialog::textChanged(const QString & szText) -{ - if(!szText.isEmpty()) - m_pReplaceButton->setEnabled(true); - else - m_pReplaceButton->setEnabled(false); -} - -void KviScriptEditorReplaceDialog::slotReplace() -{ - QString szText = ((KviScriptEditorWidget *)m_pParent)->toPlainText(); - if(m_pCheckReplaceAll->isChecked()) - emit replaceAll(m_pFindLineEdit->text(),m_pReplaceLineEdit->text()); - - szText.replace(m_pFindLineEdit->text(),m_pReplaceLineEdit->text(),Qt::CaseInsensitive); - ((KviScriptEditorWidget *)m_pParent)->setText(szText); - ((KviScriptEditorWidget *)m_pParent)->document()->setModified(true); - m_pFindLineEdit->setText(""); - m_pReplaceLineEdit->setText(""); - setTabOrder(m_pFindLineEdit,m_pReplaceLineEdit); -} - -void KviScriptEditorReplaceDialog::slotNextFind() -{ - emit nextFind(m_pFindLineEdit->text()); -} diff --git a/src/modules/editor/scripteditor.h b/src/modules/editor/scripteditor.h deleted file mode 100644 index b8611c944..000000000 --- a/src/modules/editor/scripteditor.h +++ /dev/null @@ -1,219 +0,0 @@ -#ifndef _SCRIPTEDITOR_H_ -#define _SCRIPTEDITOR_H_ - -//============================================================================= -// -// File : scripteditor.h -// Creation date : Sun Mar 28 1999 16:11:48 CEST by Szymon Stefanek -// -// This file is part of the KVIrc IRC client distribution -// Copyright (C) 1999-2010 Szymon Stefanek -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "KviScriptEditor.h" -#include "KviPointerList.h" -#include "KviSelectors.h" -#include "KviTalPopupMenu.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class QTimer; - -//typedef KviPointerList ColumnList; -class KviScriptEditorSyntaxHighlighter; -class KviScriptEditorWidget : public QTextEdit -{ - Q_OBJECT - Q_PROPERTY(bool contextSensitiveHelp READ contextSensitiveHelp) -public: - KviScriptEditorWidget(QWidget * pParent); - virtual ~KviScriptEditorWidget(); -public: - QString m_szFind; -protected: - KviScriptEditorSyntaxHighlighter * m_pSyntaxHighlighter; - QCompleter * m_pCompleter; - QStringList * m_pListModulesNames; - QStringList * m_pListCompletition; - QTimer * m_pStartTimer; - QWidget * m_pParent; - int iIndex,iModulesCount; - QString m_szHelp; -public: - KviScriptEditorSyntaxHighlighter * syntaxHighlighter(){return m_pSyntaxHighlighter;}; - void disableSyntaxHighlighter(); - void enableSyntaxHighlighter(); - - void createCompleter(QStringList &list); - - void loadCompleterFromFile(); - QCompleter * completer() const { return m_pCompleter; }; - QString textUnderCursor() const; - void updateOptions(); - //void find1(); - bool contextSensitiveHelp() const; -public slots: - void checkReadyCompleter(); - void insertCompletion(const QString & szCompletion); - void slotFind(); - void slotHelp(); - void slotReplace(); -protected slots: - void asyncCompleterCreation(); -signals: - void keyPressed(); -protected: - void contextMenuEvent(QContextMenuEvent * e); - virtual void keyPressEvent(QKeyEvent * e); -// void mouseReleaseEvent(QMouseEvent * e); -}; - -class KviScriptEditorWidgetColorOptions : public QDialog -{ - Q_OBJECT -public: - KviScriptEditorWidgetColorOptions(QWidget * pParent); - ~KviScriptEditorWidgetColorOptions(); -private: - KviPointerList * m_pSelectorInterfaceList; -protected: - KviColorSelector * addColorSelector(QWidget * pParent,const QString & txt,QColor * pOption,bool bEnabled); - -protected slots: - void okClicked(); - -}; - -class KviScriptEditorSyntaxHighlighter : public QSyntaxHighlighter -{ -public: - KviScriptEditorSyntaxHighlighter(KviScriptEditorWidget * pWidget); - virtual ~KviScriptEditorSyntaxHighlighter(); -public: - QTextEdit * m_pTextEdit; -public: - QTextEdit * textEdit(){ return m_pTextEdit; } - void highlightBlock(const QString & szText); - void updateSyntaxtTextFormat(); -private: - struct KviScriptHighlightingRule - { - QRegExp pattern; - QTextCharFormat format; - }; - - QVector highlightingRules; - QRegExp commentStartExpression; - QRegExp commentEndExpression; - - QTextCharFormat bracketFormat; - QTextCharFormat punctuationFormat; - QTextCharFormat keywordFormat; - QTextCharFormat variableFormat; - QTextCharFormat normaltextFormat; - QTextCharFormat findFormat; - QTextCharFormat functionFormat; - QTextCharFormat commentFormat; -}; - -class KviScriptEditorImplementation : public KviScriptEditor -{ - Q_OBJECT -public: - KviScriptEditorImplementation(QWidget * par); - virtual ~KviScriptEditorImplementation(); -public: - QLineEdit * m_pFindLineEdit; -protected: - KviScriptEditorWidgetColorOptions * m_pOptionsDialog; - KviScriptEditorWidget * m_pEditor; - QLabel * m_pRowColLabel; - int m_lastCursorPos; -public: - virtual void setText(const char * txt); - virtual void setText(const QString & szText); - virtual void setText(const QByteArray & szText); - virtual void getText(QString & szText); - virtual void getText(QByteArray & szText); - virtual void setFindText(const QString & szText); - virtual void setEnabled(bool bEnabled); - virtual void setReadOnly(bool bReadOnly); - void setUnHighlightedText(const QString & szText); - - - virtual void setFocus(); - virtual bool isModified(); - virtual void setModified(bool); - - int getCursor(){return m_pEditor->textCursor().position();}; - void setCursorPosition(int iPos); - int cursor(){ return m_lastCursorPos; }; - QLineEdit * findLineEdit(){ return m_pFindLineEdit; }; -protected: - virtual void focusInEvent(QFocusEvent * e); - void loadOptions(); - void saveOptions(); -protected slots: - void saveToFile(); - void loadFromFile(); - void configureColors(); - void updateRowColLabel(); - void slotFind(); - void slotReplaceAll(const QString & szToReplace, const QString & szReplaceWith); - void slotInitFind(); - void slotNextFind(const QString &); - void optionsDialogFinished(int iResult); -signals: - void find(const QString &); - void replaceAll(const QString & szToReplace, const QString & szReplaceWith); - void initFind(); - void nextFind(const QString & szText); -}; - -class KviScriptEditorReplaceDialog: public QDialog -{ - Q_OBJECT -public: - KviScriptEditorReplaceDialog(QWidget * parent = 0, const QString & szName = QString()); - ~KviScriptEditorReplaceDialog(); -public: - QLineEdit * m_pFindLineEdit; - QLineEdit * m_pReplaceLineEdit; -protected: - QPushButton * m_pReplaceButton; - QCheckBox * m_pCheckReplaceAll; - QWidget * m_pParent; -protected slots: - void textChanged(const QString &); - void slotReplace(); - void slotNextFind(); -signals: - void replaceAll(const QString &, const QString &); - void initFind(); - void nextFind(const QString &); -}; - -#endif // _SCRIPTEDITOR_H_ diff --git a/src/modules/eventeditor/CMakeLists.txt b/src/modules/eventeditor/CMakeLists.txt index fa063255f..24d672a1d 100644 --- a/src/modules/eventeditor/CMakeLists.txt +++ b/src/modules/eventeditor/CMakeLists.txt @@ -1,11 +1,11 @@ # CMakeLists for src/modules/eventeditor SET(kvieventeditor_MOC_HDRS - eventeditor.h + EventEditorWindow.h ) SET(kvieventeditor_SRCS - eventeditor.cpp + EventEditorWindow.cpp libkvieventeditor.cpp ) diff --git a/src/modules/eventeditor/EventEditorWindow.cpp b/src/modules/eventeditor/EventEditorWindow.cpp new file mode 100644 index 000000000..f8467e5b1 --- /dev/null +++ b/src/modules/eventeditor/EventEditorWindow.cpp @@ -0,0 +1,605 @@ +//============================================================================= +// +// File : EventEditorWindow.cpp +// Creation date : Mon Dec 23 2002 20:28:18 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the linkss of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "EventEditorWindow.h" + +#include "KviIconManager.h" +#include "KviOptions.h" +#include "KviLocale.h" +#include "KviImageDialog.h" +#include "KviConfigurationFile.h" +#include "KviFileDialog.h" +#include "KviFileUtils.h" +#include "KviScriptEditor.h" +#include "kvi_debug.h" +#include "KviApplication.h" +#include "KviCommandFormatter.h" +#include "kvi_fileextensions.h" +#include "KviQString.h" +#include "KviFileDialog.h" +#include "KviKvsEventManager.h" +#include "KviTalVBox.h" +#include "KviTalPopupMenu.h" + +#include +#include +#include +#include +#include +#include + +extern EventEditorWindow * g_pEventEditorWindow; + +EventEditorEventTreeWidgetItem::EventEditorEventTreeWidgetItem(QTreeWidget * par,unsigned int uEvIdx,const QString &name,const QString ¶ms) +: QTreeWidgetItem(par), m_uEventIdx(uEvIdx), m_szParams(params) +{ + setName(name); +} + +void EventEditorEventTreeWidgetItem::setName(const QString &szName) +{ + m_szName = szName; + setText(0,m_szName); +} + +EventEditorHandlerTreeWidgetItem::EventEditorHandlerTreeWidgetItem(QTreeWidgetItem * par,const QString &name,const QString &buffer,bool bEnabled) +: QTreeWidgetItem(par), m_szBuffer(buffer) +{ + m_cPos=0; + setEnabled(bEnabled); //this updates the icon too + setName(name); +} + +void EventEditorHandlerTreeWidgetItem::setName(const QString &szName) +{ + m_szName = szName; + setText(0,m_szName); +} + +void EventEditorHandlerTreeWidgetItem::setEnabled(const bool bEnabled) +{ + m_bEnabled = bEnabled; + setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(m_bEnabled ? KVI_SMALLICON_HANDLER : KVI_SMALLICON_HANDLERDISABLED)))); +} + +EventEditor::EventEditor(QWidget * par) +: QWidget(par) +{ + setObjectName("event_editor"); + + QGridLayout * l = new QGridLayout(this); + + QSplitter * spl = new QSplitter(Qt::Horizontal,this); + spl->setChildrenCollapsible(false); + + l->addWidget(spl,0,0); + + KviTalVBox * vbox = new KviTalVBox(spl); + vbox->setSpacing(0); + vbox->setMargin(0); + + m_pTreeWidget = new EventEditorTreeWidget(vbox); + + QPushButton * pb = new QPushButton(__tr2qs_ctx("&Export All To...","editor"),vbox); + connect(pb,SIGNAL(clicked()),this,SLOT(exportAllEvents())); + + KviTalVBox * box = new KviTalVBox(spl); + spl->setStretchFactor (0,20); + spl->setStretchFactor (1,80); + + box->setSpacing(0); + box->setMargin(0); + + m_pNameEditor = new QLineEdit(box); + m_pNameEditor->setToolTip(__tr2qs_ctx("Edit the event handler name.","editor")); + + m_pEditor = KviScriptEditor::createInstance(box); + m_pEditor->setFocus(); + m_bOneTimeSetupDone = false; + m_pLastEditedItem = 0; +} + +EventEditor::~EventEditor() +{ + KviScriptEditor::destroyInstance(m_pEditor); +} + +void EventEditor::oneTimeSetup() +{ + if(m_bOneTimeSetupDone)return; + m_bOneTimeSetupDone = true; + + EventEditorEventTreeWidgetItem * it; + + for(unsigned int i = 0;i < KVI_KVS_NUM_APP_EVENTS;i++) + { + KviKvsEvent * e = KviKvsEventManager::instance()->appEvent(i); + + it = new EventEditorEventTreeWidgetItem(m_pTreeWidget,i,e->name(),e->parameterDescription()); + if(KviPointerList * l = e->handlers()) + { + for(KviKvsEventHandler * s = l->first();s;s = l->next()) + { + if(s->type() == KviKvsEventHandler::Script) + { + new EventEditorHandlerTreeWidgetItem(it,((KviKvsScriptEventHandler *)s)->name(), + ((KviKvsScriptEventHandler *)s)->code(),((KviKvsScriptEventHandler *)s)->isEnabled()); + } + } + } + it->setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(it->childCount() ? KVI_SMALLICON_EVENT : KVI_SMALLICON_EVENTNOHANDLERS)))); + } + + connect(m_pTreeWidget,SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),this,SLOT(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *))); + connect(m_pTreeWidget,SIGNAL(rightButtonPressed(QTreeWidgetItem *,QPoint)), + this,SLOT(itemPressed(QTreeWidgetItem *,QPoint))); + connect(KviKvsEventManager::instance(),SIGNAL(eventHandlerDisabled(const QString &)),this,SLOT(eventHandlerDisabled(const QString &))); + m_pContextPopup = new KviTalPopupMenu(this); + m_pTreeWidget->sortItems(0,Qt::AscendingOrder); +} +void EventEditor::eventHandlerDisabled(const QString &szHandler) +{ + QString szEventName=szHandler.split("::")[0]; + QString szHandlerName=szHandler.split("::")[1]; + qDebug("Handler %s of event %s : disabled",szHandlerName.toUtf8().data(),szEventName.toUtf8().data()); + for(int i=0;itopLevelItemCount();i++) + { + EventEditorEventTreeWidgetItem *pItem=(EventEditorEventTreeWidgetItem*)m_pTreeWidget->topLevelItem(i); + if(!KviQString::equalCI(szEventName,pItem->name())) continue; + for(int j=0;jchildCount();j++) + { + if(KviQString::equalCI(szHandlerName,((EventEditorHandlerTreeWidgetItem *)pItem->child(j))->name())) + { + ((EventEditorHandlerTreeWidgetItem *)pItem->child(j))->setEnabled(false); + return; + } + + } + } + +} + +EventEditorTreeWidget::EventEditorTreeWidget(QWidget * par) +: QTreeWidget(par) +{ + setColumnCount (1); + setHeaderLabel(__tr2qs_ctx("Event","editor")); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setSortingEnabled(true); + setRootIsDecorated(true); + setAnimated(true); +} + +void EventEditorTreeWidget::mousePressEvent (QMouseEvent *e) +{ + if (e->button() == Qt::RightButton) + { + QTreeWidgetItem *i=itemAt(e->pos()); + if (i) emit rightButtonPressed(i,QCursor::pos()); + } + QTreeWidget::mousePressEvent(e); +} + +void EventEditor::itemPressed(QTreeWidgetItem *it,const QPoint &pnt) +{ + KVI_ASSERT(m_bOneTimeSetupDone); + + if(it) + { + m_pContextPopup->clear(); + if(it->parent()) + { + QString tmp; + if(!(((EventEditorHandlerTreeWidgetItem *)it)->m_bEnabled)) + m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_HANDLER)), + __tr2qs_ctx("&Enable Handler","editor"),this,SLOT(toggleCurrentHandlerEnabled())); + else + m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_HANDLERDISABLED)), + __tr2qs_ctx("&Disable Handler","editor"),this,SLOT(toggleCurrentHandlerEnabled())); + + m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)), + __tr2qs_ctx("Re&move Handler","editor"), + this,SLOT(removeCurrentHandler())); + m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)), + __tr2qs_ctx("&Export Handler To...","editor"), + this,SLOT(exportCurrentHandler())); + } else { + m_pContextPopup->insertItem( + *(g_pIconManager->getSmallIcon(KVI_SMALLICON_HANDLER)), + __tr2qs_ctx("&New Handler","editor"), + this,SLOT(addHandlerForCurrentEvent())); + } + + m_pContextPopup->popup(pnt); + } +} + +void EventEditor::getUniqueHandlerName(EventEditorEventTreeWidgetItem *it,QString &buffer) +{ + KVI_ASSERT(m_bOneTimeSetupDone); + + QString newName = buffer; + if(newName.isEmpty())newName = __tr2qs_ctx("unnamed","editor"); + + bool bFound = true; + int idx = 1; + + while(bFound) + { + bFound = false; + + for(int i=0;ichildCount();i++) + //for(EventEditorHandlerTreeWidgetItem * ch = (EventEditorHandlerTreeWidgetItem *)(it->firstChild());ch;ch = (EventEditorHandlerTreeWidgetItem *)ch->nextSibling()) + { + if(KviQString::equalCI(newName,((EventEditorHandlerTreeWidgetItem *)it->child(i))->m_szName)) + { + bFound = true; + KviQString::sprintf(newName,"%Q_%d",&buffer,idx); + idx++; + break; + } + } + } + + buffer = newName; +} + +void EventEditor::addHandlerForCurrentEvent() +{ + KVI_ASSERT(m_bOneTimeSetupDone); + + if(!m_pTreeWidget->selectedItems().isEmpty()) + { + QTreeWidgetItem * it = m_pTreeWidget->selectedItems().first(); + + if(it->parent() == 0) + { + if(it->childCount()==0) + it->setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_EVENT)))); + + QString buffer = __tr2qs_ctx("default","editor"); + getUniqueHandlerName((EventEditorEventTreeWidgetItem *)it,buffer); + QTreeWidgetItem * ch = new EventEditorHandlerTreeWidgetItem(it,buffer,"",true); + it->setExpanded(true); + ch->setSelected(true); + } + } +} + +void EventEditor::removeCurrentHandler() +{ + KVI_ASSERT(m_bOneTimeSetupDone); + if(m_pLastEditedItem) + { + QTreeWidgetItem * it = m_pLastEditedItem; + QTreeWidgetItem * parent = m_pLastEditedItem->parent(); + m_pLastEditedItem = 0; + delete it; + + if(parent) + { + if(parent->childCount()==0) + parent->setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_EVENTNOHANDLERS)))); + } + + m_pEditor->setEnabled(false); + m_pNameEditor->setEnabled(false); + } +} + +void EventEditor::toggleCurrentHandlerEnabled() +{ + KVI_ASSERT(m_bOneTimeSetupDone); + if(m_pLastEditedItem) + { + m_pLastEditedItem->setEnabled(!(m_pLastEditedItem->m_bEnabled)); + m_pTreeWidget->repaint(m_pTreeWidget->visualItemRect(m_pLastEditedItem)); + currentItemChanged(m_pLastEditedItem,0); + } +} + +void EventEditor::commit() +{ + if(!m_bOneTimeSetupDone)return; // nothing to commit + + saveLastEditedItem(); + KviKvsEventManager::instance()->removeAllScriptAppHandlers(); + + int count=m_pTreeWidget->topLevelItemCount(); + for (int i=0;itopLevelItem(i); + int ccount = it->childCount(); + if(ccount > 0) + { + QString szContext; + + for(int j=0;jchild(j); + KviQString::sprintf(szContext,"%Q::%Q",&(((EventEditorEventTreeWidgetItem *)it)->m_szName),&(((EventEditorHandlerTreeWidgetItem *)ch)->m_szName)); + KviKvsScriptEventHandler * s = KviKvsScriptEventHandler::createInstance( // msvc workaround + ((EventEditorHandlerTreeWidgetItem *)ch)->m_szName, + szContext, + ((EventEditorHandlerTreeWidgetItem *)ch)->m_szBuffer, + ((EventEditorHandlerTreeWidgetItem *)ch)->m_bEnabled + ); + + KviKvsEventManager::instance()->addAppHandler(((EventEditorEventTreeWidgetItem *)it)->m_uEventIdx,s); + } + } + } + + g_pApp->saveAppEvents(); +} + +void EventEditor::saveLastEditedItem() +{ + KVI_ASSERT(m_bOneTimeSetupDone); + if(!m_pLastEditedItem)return; + ((EventEditorHandlerTreeWidgetItem *)m_pLastEditedItem)->setCursorPosition(m_pEditor->getCursor()); + QString buffer = m_pNameEditor->text(); + //not-so elaborate fix for #218, we'd better rework this + buffer.replace(QRegExp("[^A-Za-z0-9_]"), ""); + if(!KviQString::equalCI(buffer,m_pLastEditedItem->m_szName)) + { + getUniqueHandlerName((EventEditorEventTreeWidgetItem *)(m_pLastEditedItem->parent()),buffer); + } + + m_pLastEditedItem->setName(buffer); + QString tmp; + m_pEditor->getText(tmp); + + m_pLastEditedItem->m_szBuffer = tmp; +} + +void EventEditor::currentItemChanged(QTreeWidgetItem * it,QTreeWidgetItem *) +{ + KVI_ASSERT(m_bOneTimeSetupDone); + saveLastEditedItem(); + + if(!it) + { + m_pNameEditor->setText(__tr2qs_ctx("No item selected","editor")); + m_pEditor->setText(""); + m_pEditor->setEnabled(false); + return; + } + + if(it->parent()) + { + m_pLastEditedItem = (EventEditorHandlerTreeWidgetItem *)it; + m_pNameEditor->setEnabled(true); + m_pNameEditor->setText(m_pLastEditedItem->name()); + m_pEditor->setEnabled(true); + m_pEditor->setFocus(); + m_pEditor->setText(m_pLastEditedItem->m_szBuffer); + m_pEditor->setCursorPosition(((EventEditorHandlerTreeWidgetItem *)it)->cursorPosition()); + } else { + m_pLastEditedItem = 0; + m_pNameEditor->setEnabled(false); + m_pNameEditor->setText(""); + m_pEditor->setEnabled(false); + QString parms = ((EventEditorEventTreeWidgetItem *)it)->m_szParams; + if(parms.isEmpty())parms = __tr2qs_ctx("none","editor"); + KviCommandFormatter::indent(parms); + KviCommandFormatter::indent(parms); + QString tmp; + KviQString::sprintf(tmp,__tr2qs_ctx("\n\nEvent:\n%s\n\nParameters:\n%s","editor"), + ((EventEditorEventTreeWidgetItem *)it)->m_szName.toUtf8().data(),parms.toUtf8().data()); + m_pEditor->setText(tmp); + } +} + +void EventEditor::showEvent(QShowEvent *e) +{ + oneTimeSetup(); + QWidget::showEvent(e); +} + +void EventEditor::getExportEventBuffer(QString &buffer,EventEditorHandlerTreeWidgetItem * it) +{ + if(!it->parent())return; + + QString szBuf = it->m_szBuffer; + + KviCommandFormatter::blockFromBuffer(szBuf); + + buffer = "event("; + buffer += ((EventEditorEventTreeWidgetItem *)(it->parent()))->m_szName; + buffer += ","; + buffer += it->m_szName; + buffer += ")\n"; + buffer += szBuf; + buffer += "\n"; + + if(!it->m_bEnabled) + { + buffer += "\n"; + buffer += "eventctl -d "; + buffer += ((EventEditorEventTreeWidgetItem *)(it->parent()))->m_szName; + buffer += " "; + buffer += it->m_szName; + } +} + +void EventEditor::exportCurrentHandler() +{ + if(!m_pLastEditedItem)return; + saveLastEditedItem(); + if(!m_pLastEditedItem)return; + + QString szName = QDir::homePath(); + if(!szName.endsWith(QString(KVI_PATH_SEPARATOR)))szName += KVI_PATH_SEPARATOR; + szName += ((EventEditorEventTreeWidgetItem *)(m_pLastEditedItem->parent()))->m_szName; + szName += "."; + szName += m_pLastEditedItem->m_szName; + szName += ".kvs"; + + QString szFile; + + if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs_ctx("Choose a Filename - KVIrc","editor"),szName,KVI_FILTER_SCRIPT,true,true,true))return; + + QString szOut; + getExportEventBuffer(szOut,m_pLastEditedItem); + + if(!KviFileUtils::writeFile(szFile,szOut)) + { + QMessageBox::warning(this,__tr2qs_ctx("Write Failed - KVIrc","editor"),__tr2qs_ctx("Unable to write to the event file.","editor"),__tr2qs_ctx("&OK","editor")); + } +} + +void EventEditor::exportAllEvents() +{ + saveLastEditedItem(); + + QString out; + + int count=m_pTreeWidget->topLevelItemCount(); + for (int i=0;itopLevelItem(i); + + int ccount = it->childCount(); + + for(int j=0;jchild(j); + + QString tmp; + getExportEventBuffer(tmp,item); + out += tmp; + out += "\n"; + } + } + + QString szName = QDir::homePath(); + if(!szName.endsWith(QString(KVI_PATH_SEPARATOR)))szName += KVI_PATH_SEPARATOR; + szName += "events.kvs"; + + QString szFile; + + if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs_ctx("Choose a Filename - KVIrc","editor"),szName,QString(),true,true))return; + + if(!KviFileUtils::writeFile(szFile,out)) + { + QMessageBox::warning(this,__tr2qs_ctx("Write Failed - KVIrc","editor"),__tr2qs_ctx("Unable to write to the events file.","editor"),__tr2qs_ctx("OK","editor")); + } +} + + +EventEditorWindow::EventEditorWindow(KviMainWindow * lpFrm) +: KviWindow(KVI_WINDOW_TYPE_SCRIPTEDITOR,lpFrm,"eventeditor",0) +{ + g_pEventEditorWindow = this; + + QGridLayout * g = new QGridLayout(); + m_pEditor = new EventEditor(this); + g->addWidget(m_pEditor,0,0,1,4); + + QPushButton * btn = new QPushButton(__tr2qs_ctx("&OK","editor"),this); + connect(btn,SIGNAL(clicked()),this,SLOT(okClicked())); + btn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT))); + g->addWidget(btn,1,1); + + btn = new QPushButton(__tr2qs_ctx("&Apply","editor"),this); + connect(btn,SIGNAL(clicked()),this,SLOT(applyClicked())); + btn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT))); + g->addWidget(btn,1,2); + + btn = new QPushButton(__tr2qs_ctx("Cancel","editor"),this); + connect(btn,SIGNAL(clicked()),this,SLOT(cancelClicked())); + btn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD))); + g->addWidget(btn,1,3); + + g->setRowStretch(0,1); + g->setColumnStretch(0,1); + setLayout(g); +} + +EventEditorWindow::~EventEditorWindow() +{ + g_pEventEditorWindow = 0; +} + +void EventEditorWindow::okClicked() +{ + m_pEditor->commit(); + close(); +} + +void EventEditorWindow::applyClicked() +{ + m_pEditor->commit(); +} + +void EventEditorWindow::cancelClicked() +{ + close(); +} + +QPixmap * EventEditorWindow::myIconPtr() +{ + return g_pIconManager->getSmallIcon(KVI_SMALLICON_EVENT); +} + +void EventEditorWindow::fillCaptionBuffers() +{ + m_szPlainTextCaption = __tr2qs_ctx("Event Editor","editor"); +} + +void EventEditorWindow::getConfigGroupName(QString &szName) +{ + szName = "eventeditor"; +} + +void EventEditorWindow::saveProperties(KviConfigurationFile *) //cfg +{ +/* +#ifdef COMPILE_SCRIPTTOOLBAR + cfg->writeEntry("Sizes",m_pEditor->sizes()); + cfg->writeEntry("LastEvent",m_pEditor->lastEditedEvent().ptr()); + //qDebug("LAST EDITED=%s",m_pEditor->lastEditedEvent().ptr()); +#endif // COMPILE_SCRIPTTOOLBAR +*/ +} + +void EventEditorWindow::loadProperties(KviConfigurationFile *) //cfg +{ +/* +#ifdef COMPILE_SCRIPTTOOLBAR + QValueList def; + def.append(20); + def.append(80); + m_pEditor->setSizes(cfg->readIntListEntry("Sizes",def)); + KviCString tmp = cfg->readEntry("LastEvent",""); + m_pEditor->editEvent(tmp); + //qDebug("LAST EDITED WAS %s",tmp.ptr()); +#endif // COMPILE_SCRIPTTOOLBAR +*/ +} diff --git a/src/modules/eventeditor/EventEditorWindow.h b/src/modules/eventeditor/EventEditorWindow.h new file mode 100644 index 000000000..cd0b0f105 --- /dev/null +++ b/src/modules/eventeditor/EventEditorWindow.h @@ -0,0 +1,136 @@ +#ifndef _EVENTEDITOR_H_ +#define _EVENTEDITOR_H_ +//============================================================================= +// +// File : EventEditorWindow.h +// Creation date : Mon Dec 23 2002 20:24:55 CEST by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the linkss of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviWindow.h" +#include "KviCString.h" +#include "KviTalPopupMenu.h" + +#include +#include +#include + +class KviScriptEditor; + +class EventEditorEventTreeWidgetItem : public QTreeWidgetItem +{ +public: + unsigned int m_uEventIdx; + QString m_szName; + QString m_szParams; +public: + EventEditorEventTreeWidgetItem(QTreeWidget * par,unsigned int uEvIdx,const QString &name,const QString ¶ms); + ~EventEditorEventTreeWidgetItem() {}; +public: + void setName(const QString &szName); + QString name() const { return m_szName; }; +}; + +class EventEditorHandlerTreeWidgetItem : public QTreeWidgetItem +{ +public: + QString m_szName; + QString m_szBuffer; + bool m_bEnabled; + int m_cPos; +public: + EventEditorHandlerTreeWidgetItem(QTreeWidgetItem * par,const QString &name,const QString &buffer,bool bEnabled); + ~EventEditorHandlerTreeWidgetItem() {}; +public: + const int & cursorPosition(){return m_cPos; }; + void setCursorPosition(const int &cPos){qDebug("set cursor to %d",cPos); m_cPos = cPos; }; + + void setName(const QString &szName); + QString name() const { return m_szName; }; + void setEnabled(const bool bEnabled); +}; + +class EventEditorTreeWidget : public QTreeWidget +{ + Q_OBJECT +public: + EventEditorTreeWidget(QWidget*); + ~EventEditorTreeWidget(){}; +protected: + + void mousePressEvent (QMouseEvent *e); +signals: + void rightButtonPressed(QTreeWidgetItem *,QPoint); +}; + +class EventEditor : public QWidget +{ + Q_OBJECT +public: + EventEditor(QWidget * par); + ~EventEditor(); +public: + KviScriptEditor * m_pEditor; + EventEditorTreeWidget * m_pTreeWidget; + QLineEdit * m_pNameEditor; + KviTalPopupMenu * m_pContextPopup; + EventEditorHandlerTreeWidgetItem * m_pLastEditedItem; + bool m_bOneTimeSetupDone; +public: + void commit(); + void saveLastEditedItem(); + void getUniqueHandlerName(EventEditorEventTreeWidgetItem *it,QString &buffer); + void getExportEventBuffer(QString &szBuffer,EventEditorHandlerTreeWidgetItem * it); +protected slots: + void currentItemChanged(QTreeWidgetItem *it,QTreeWidgetItem *); + void itemPressed(QTreeWidgetItem *it,const QPoint &pnt); + void toggleCurrentHandlerEnabled(); + void removeCurrentHandler(); + void addHandlerForCurrentEvent(); + void exportAllEvents(); + void exportCurrentHandler(); + void eventHandlerDisabled(const QString &szName); +protected: + void showEvent(QShowEvent *e); +private: + void oneTimeSetup(); +}; + +class EventEditorWindow : public KviWindow +{ + Q_OBJECT +public: + EventEditorWindow(KviMainWindow * lpFrm); + ~EventEditorWindow(); +protected: + EventEditor * m_pEditor; +protected: + virtual QPixmap * myIconPtr(); + virtual void fillCaptionBuffers(); + virtual void getConfigGroupName(QString &szName); + virtual void saveProperties(KviConfigurationFile *); + virtual void loadProperties(KviConfigurationFile *); +protected slots: + void cancelClicked(); + void okClicked(); + void applyClicked(); +}; + +#endif //_EVENTEDITOR_H_ diff --git a/src/modules/eventeditor/eventeditor.cpp b/src/modules/eventeditor/eventeditor.cpp deleted file mode 100644 index 1b5be86e6..000000000 --- a/src/modules/eventeditor/eventeditor.cpp +++ /dev/null @@ -1,605 +0,0 @@ -//============================================================================= -// -// File : eventeditor.cpp -// Creation date : Mon Dec 23 2002 20:28:18 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the linkss of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "eventeditor.h" - -#include "KviIconManager.h" -#include "KviOptions.h" -#include "KviLocale.h" -#include "KviImageDialog.h" -#include "KviConfigurationFile.h" -#include "KviFileDialog.h" -#include "KviFileUtils.h" -#include "KviScriptEditor.h" -#include "kvi_debug.h" -#include "KviApplication.h" -#include "KviCommandFormatter.h" -#include "kvi_fileextensions.h" -#include "KviQString.h" -#include "KviFileDialog.h" -#include "KviKvsEventManager.h" -#include "KviTalVBox.h" -#include "KviTalPopupMenu.h" - -#include -#include -#include -#include -#include -#include - -extern KviEventEditorWindow * g_pEventEditorWindow; - -KviEventTreeWidgetItem::KviEventTreeWidgetItem(QTreeWidget * par,unsigned int uEvIdx,const QString &name,const QString ¶ms) -: QTreeWidgetItem(par), m_uEventIdx(uEvIdx), m_szParams(params) -{ - setName(name); -} - -void KviEventTreeWidgetItem::setName(const QString &szName) -{ - m_szName = szName; - setText(0,m_szName); -} - -KviEventHandlerTreeWidgetItem::KviEventHandlerTreeWidgetItem(QTreeWidgetItem * par,const QString &name,const QString &buffer,bool bEnabled) -: QTreeWidgetItem(par), m_szBuffer(buffer) -{ - m_cPos=0; - setEnabled(bEnabled); //this updates the icon too - setName(name); -} - -void KviEventHandlerTreeWidgetItem::setName(const QString &szName) -{ - m_szName = szName; - setText(0,m_szName); -} - -void KviEventHandlerTreeWidgetItem::setEnabled(const bool bEnabled) -{ - m_bEnabled = bEnabled; - setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(m_bEnabled ? KVI_SMALLICON_HANDLER : KVI_SMALLICON_HANDLERDISABLED)))); -} - -KviEventEditor::KviEventEditor(QWidget * par) -: QWidget(par) -{ - setObjectName("event_editor"); - - QGridLayout * l = new QGridLayout(this); - - QSplitter * spl = new QSplitter(Qt::Horizontal,this); - spl->setChildrenCollapsible(false); - - l->addWidget(spl,0,0); - - KviTalVBox * vbox = new KviTalVBox(spl); - vbox->setSpacing(0); - vbox->setMargin(0); - - m_pTreeWidget = new KviEventEditorTreeWidget(vbox); - - QPushButton * pb = new QPushButton(__tr2qs_ctx("&Export All To...","editor"),vbox); - connect(pb,SIGNAL(clicked()),this,SLOT(exportAllEvents())); - - KviTalVBox * box = new KviTalVBox(spl); - spl->setStretchFactor (0,20); - spl->setStretchFactor (1,80); - - box->setSpacing(0); - box->setMargin(0); - - m_pNameEditor = new QLineEdit(box); - m_pNameEditor->setToolTip(__tr2qs_ctx("Edit the event handler name.","editor")); - - m_pEditor = KviScriptEditor::createInstance(box); - m_pEditor->setFocus(); - m_bOneTimeSetupDone = false; - m_pLastEditedItem = 0; -} - -KviEventEditor::~KviEventEditor() -{ - KviScriptEditor::destroyInstance(m_pEditor); -} - -void KviEventEditor::oneTimeSetup() -{ - if(m_bOneTimeSetupDone)return; - m_bOneTimeSetupDone = true; - - KviEventTreeWidgetItem * it; - - for(unsigned int i = 0;i < KVI_KVS_NUM_APP_EVENTS;i++) - { - KviKvsEvent * e = KviKvsEventManager::instance()->appEvent(i); - - it = new KviEventTreeWidgetItem(m_pTreeWidget,i,e->name(),e->parameterDescription()); - if(KviPointerList * l = e->handlers()) - { - for(KviKvsEventHandler * s = l->first();s;s = l->next()) - { - if(s->type() == KviKvsEventHandler::Script) - { - new KviEventHandlerTreeWidgetItem(it,((KviKvsScriptEventHandler *)s)->name(), - ((KviKvsScriptEventHandler *)s)->code(),((KviKvsScriptEventHandler *)s)->isEnabled()); - } - } - } - it->setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(it->childCount() ? KVI_SMALLICON_EVENT : KVI_SMALLICON_EVENTNOHANDLERS)))); - } - - connect(m_pTreeWidget,SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),this,SLOT(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *))); - connect(m_pTreeWidget,SIGNAL(rightButtonPressed(QTreeWidgetItem *,QPoint)), - this,SLOT(itemPressed(QTreeWidgetItem *,QPoint))); - connect(KviKvsEventManager::instance(),SIGNAL(eventHandlerDisabled(const QString &)),this,SLOT(eventHandlerDisabled(const QString &))); - m_pContextPopup = new KviTalPopupMenu(this); - m_pTreeWidget->sortItems(0,Qt::AscendingOrder); -} -void KviEventEditor::eventHandlerDisabled(const QString &szHandler) -{ - QString szEventName=szHandler.split("::")[0]; - QString szHandlerName=szHandler.split("::")[1]; - qDebug("Handler %s of event %s : disabled",szHandlerName.toUtf8().data(),szEventName.toUtf8().data()); - for(int i=0;itopLevelItemCount();i++) - { - KviEventTreeWidgetItem *pItem=(KviEventTreeWidgetItem*)m_pTreeWidget->topLevelItem(i); - if(!KviQString::equalCI(szEventName,pItem->name())) continue; - for(int j=0;jchildCount();j++) - { - if(KviQString::equalCI(szHandlerName,((KviEventHandlerTreeWidgetItem *)pItem->child(j))->name())) - { - ((KviEventHandlerTreeWidgetItem *)pItem->child(j))->setEnabled(false); - return; - } - - } - } - -} - -KviEventEditorTreeWidget::KviEventEditorTreeWidget(QWidget * par) -: QTreeWidget(par) -{ - setColumnCount (1); - setHeaderLabel(__tr2qs_ctx("Event","editor")); - setSelectionMode(QAbstractItemView::ExtendedSelection); - setSortingEnabled(true); - setRootIsDecorated(true); - setAnimated(true); -} - -void KviEventEditorTreeWidget::mousePressEvent (QMouseEvent *e) -{ - if (e->button() == Qt::RightButton) - { - QTreeWidgetItem *i=itemAt(e->pos()); - if (i) emit rightButtonPressed(i,QCursor::pos()); - } - QTreeWidget::mousePressEvent(e); -} - -void KviEventEditor::itemPressed(QTreeWidgetItem *it,const QPoint &pnt) -{ - KVI_ASSERT(m_bOneTimeSetupDone); - - if(it) - { - m_pContextPopup->clear(); - if(it->parent()) - { - QString tmp; - if(!(((KviEventHandlerTreeWidgetItem *)it)->m_bEnabled)) - m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_HANDLER)), - __tr2qs_ctx("&Enable Handler","editor"),this,SLOT(toggleCurrentHandlerEnabled())); - else - m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_HANDLERDISABLED)), - __tr2qs_ctx("&Disable Handler","editor"),this,SLOT(toggleCurrentHandlerEnabled())); - - m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)), - __tr2qs_ctx("Re&move Handler","editor"), - this,SLOT(removeCurrentHandler())); - m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)), - __tr2qs_ctx("&Export Handler To...","editor"), - this,SLOT(exportCurrentHandler())); - } else { - m_pContextPopup->insertItem( - *(g_pIconManager->getSmallIcon(KVI_SMALLICON_HANDLER)), - __tr2qs_ctx("&New Handler","editor"), - this,SLOT(addHandlerForCurrentEvent())); - } - - m_pContextPopup->popup(pnt); - } -} - -void KviEventEditor::getUniqueHandlerName(KviEventTreeWidgetItem *it,QString &buffer) -{ - KVI_ASSERT(m_bOneTimeSetupDone); - - QString newName = buffer; - if(newName.isEmpty())newName = __tr2qs_ctx("unnamed","editor"); - - bool bFound = true; - int idx = 1; - - while(bFound) - { - bFound = false; - - for(int i=0;ichildCount();i++) - //for(KviEventHandlerTreeWidgetItem * ch = (KviEventHandlerTreeWidgetItem *)(it->firstChild());ch;ch = (KviEventHandlerTreeWidgetItem *)ch->nextSibling()) - { - if(KviQString::equalCI(newName,((KviEventHandlerTreeWidgetItem *)it->child(i))->m_szName)) - { - bFound = true; - KviQString::sprintf(newName,"%Q_%d",&buffer,idx); - idx++; - break; - } - } - } - - buffer = newName; -} - -void KviEventEditor::addHandlerForCurrentEvent() -{ - KVI_ASSERT(m_bOneTimeSetupDone); - - if(!m_pTreeWidget->selectedItems().isEmpty()) - { - QTreeWidgetItem * it = m_pTreeWidget->selectedItems().first(); - - if(it->parent() == 0) - { - if(it->childCount()==0) - it->setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_EVENT)))); - - QString buffer = __tr2qs_ctx("default","editor"); - getUniqueHandlerName((KviEventTreeWidgetItem *)it,buffer); - QTreeWidgetItem * ch = new KviEventHandlerTreeWidgetItem(it,buffer,"",true); - it->setExpanded(true); - ch->setSelected(true); - } - } -} - -void KviEventEditor::removeCurrentHandler() -{ - KVI_ASSERT(m_bOneTimeSetupDone); - if(m_pLastEditedItem) - { - QTreeWidgetItem * it = m_pLastEditedItem; - QTreeWidgetItem * parent = m_pLastEditedItem->parent(); - m_pLastEditedItem = 0; - delete it; - - if(parent) - { - if(parent->childCount()==0) - parent->setIcon(0,QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_EVENTNOHANDLERS)))); - } - - m_pEditor->setEnabled(false); - m_pNameEditor->setEnabled(false); - } -} - -void KviEventEditor::toggleCurrentHandlerEnabled() -{ - KVI_ASSERT(m_bOneTimeSetupDone); - if(m_pLastEditedItem) - { - m_pLastEditedItem->setEnabled(!(m_pLastEditedItem->m_bEnabled)); - m_pTreeWidget->repaint(m_pTreeWidget->visualItemRect(m_pLastEditedItem)); - currentItemChanged(m_pLastEditedItem,0); - } -} - -void KviEventEditor::commit() -{ - if(!m_bOneTimeSetupDone)return; // nothing to commit - - saveLastEditedItem(); - KviKvsEventManager::instance()->removeAllScriptAppHandlers(); - - int count=m_pTreeWidget->topLevelItemCount(); - for (int i=0;itopLevelItem(i); - int ccount = it->childCount(); - if(ccount > 0) - { - QString szContext; - - for(int j=0;jchild(j); - KviQString::sprintf(szContext,"%Q::%Q",&(((KviEventTreeWidgetItem *)it)->m_szName),&(((KviEventHandlerTreeWidgetItem *)ch)->m_szName)); - KviKvsScriptEventHandler * s = KviKvsScriptEventHandler::createInstance( // msvc workaround - ((KviEventHandlerTreeWidgetItem *)ch)->m_szName, - szContext, - ((KviEventHandlerTreeWidgetItem *)ch)->m_szBuffer, - ((KviEventHandlerTreeWidgetItem *)ch)->m_bEnabled - ); - - KviKvsEventManager::instance()->addAppHandler(((KviEventTreeWidgetItem *)it)->m_uEventIdx,s); - } - } - } - - g_pApp->saveAppEvents(); -} - -void KviEventEditor::saveLastEditedItem() -{ - KVI_ASSERT(m_bOneTimeSetupDone); - if(!m_pLastEditedItem)return; - ((KviEventHandlerTreeWidgetItem *)m_pLastEditedItem)->setCursorPosition(m_pEditor->getCursor()); - QString buffer = m_pNameEditor->text(); - //not-so elaborate fix for #218, we'd better rework this - buffer.replace(QRegExp("[^A-Za-z0-9_]"), ""); - if(!KviQString::equalCI(buffer,m_pLastEditedItem->m_szName)) - { - getUniqueHandlerName((KviEventTreeWidgetItem *)(m_pLastEditedItem->parent()),buffer); - } - - m_pLastEditedItem->setName(buffer); - QString tmp; - m_pEditor->getText(tmp); - - m_pLastEditedItem->m_szBuffer = tmp; -} - -void KviEventEditor::currentItemChanged(QTreeWidgetItem * it,QTreeWidgetItem *) -{ - KVI_ASSERT(m_bOneTimeSetupDone); - saveLastEditedItem(); - - if(!it) - { - m_pNameEditor->setText(__tr2qs_ctx("No item selected","editor")); - m_pEditor->setText(""); - m_pEditor->setEnabled(false); - return; - } - - if(it->parent()) - { - m_pLastEditedItem = (KviEventHandlerTreeWidgetItem *)it; - m_pNameEditor->setEnabled(true); - m_pNameEditor->setText(m_pLastEditedItem->name()); - m_pEditor->setEnabled(true); - m_pEditor->setFocus(); - m_pEditor->setText(m_pLastEditedItem->m_szBuffer); - m_pEditor->setCursorPosition(((KviEventHandlerTreeWidgetItem *)it)->cursorPosition()); - } else { - m_pLastEditedItem = 0; - m_pNameEditor->setEnabled(false); - m_pNameEditor->setText(""); - m_pEditor->setEnabled(false); - QString parms = ((KviEventTreeWidgetItem *)it)->m_szParams; - if(parms.isEmpty())parms = __tr2qs_ctx("none","editor"); - KviCommandFormatter::indent(parms); - KviCommandFormatter::indent(parms); - QString tmp; - KviQString::sprintf(tmp,__tr2qs_ctx("\n\nEvent:\n%s\n\nParameters:\n%s","editor"), - ((KviEventTreeWidgetItem *)it)->m_szName.toUtf8().data(),parms.toUtf8().data()); - m_pEditor->setText(tmp); - } -} - -void KviEventEditor::showEvent(QShowEvent *e) -{ - oneTimeSetup(); - QWidget::showEvent(e); -} - -void KviEventEditor::getExportEventBuffer(QString &buffer,KviEventHandlerTreeWidgetItem * it) -{ - if(!it->parent())return; - - QString szBuf = it->m_szBuffer; - - KviCommandFormatter::blockFromBuffer(szBuf); - - buffer = "event("; - buffer += ((KviEventTreeWidgetItem *)(it->parent()))->m_szName; - buffer += ","; - buffer += it->m_szName; - buffer += ")\n"; - buffer += szBuf; - buffer += "\n"; - - if(!it->m_bEnabled) - { - buffer += "\n"; - buffer += "eventctl -d "; - buffer += ((KviEventTreeWidgetItem *)(it->parent()))->m_szName; - buffer += " "; - buffer += it->m_szName; - } -} - -void KviEventEditor::exportCurrentHandler() -{ - if(!m_pLastEditedItem)return; - saveLastEditedItem(); - if(!m_pLastEditedItem)return; - - QString szName = QDir::homePath(); - if(!szName.endsWith(QString(KVI_PATH_SEPARATOR)))szName += KVI_PATH_SEPARATOR; - szName += ((KviEventTreeWidgetItem *)(m_pLastEditedItem->parent()))->m_szName; - szName += "."; - szName += m_pLastEditedItem->m_szName; - szName += ".kvs"; - - QString szFile; - - if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs_ctx("Choose a Filename - KVIrc","editor"),szName,KVI_FILTER_SCRIPT,true,true,true))return; - - QString szOut; - getExportEventBuffer(szOut,m_pLastEditedItem); - - if(!KviFileUtils::writeFile(szFile,szOut)) - { - QMessageBox::warning(this,__tr2qs_ctx("Write Failed - KVIrc","editor"),__tr2qs_ctx("Unable to write to the event file.","editor"),__tr2qs_ctx("&OK","editor")); - } -} - -void KviEventEditor::exportAllEvents() -{ - saveLastEditedItem(); - - QString out; - - int count=m_pTreeWidget->topLevelItemCount(); - for (int i=0;itopLevelItem(i); - - int ccount = it->childCount(); - - for(int j=0;jchild(j); - - QString tmp; - getExportEventBuffer(tmp,item); - out += tmp; - out += "\n"; - } - } - - QString szName = QDir::homePath(); - if(!szName.endsWith(QString(KVI_PATH_SEPARATOR)))szName += KVI_PATH_SEPARATOR; - szName += "events.kvs"; - - QString szFile; - - if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs_ctx("Choose a Filename - KVIrc","editor"),szName,QString(),true,true))return; - - if(!KviFileUtils::writeFile(szFile,out)) - { - QMessageBox::warning(this,__tr2qs_ctx("Write Failed - KVIrc","editor"),__tr2qs_ctx("Unable to write to the events file.","editor"),__tr2qs_ctx("OK","editor")); - } -} - - -KviEventEditorWindow::KviEventEditorWindow(KviMainWindow * lpFrm) -: KviWindow(KVI_WINDOW_TYPE_SCRIPTEDITOR,lpFrm,"eventeditor",0) -{ - g_pEventEditorWindow = this; - - QGridLayout * g = new QGridLayout(); - m_pEditor = new KviEventEditor(this); - g->addWidget(m_pEditor,0,0,1,4); - - QPushButton * btn = new QPushButton(__tr2qs_ctx("&OK","editor"),this); - connect(btn,SIGNAL(clicked()),this,SLOT(okClicked())); - btn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT))); - g->addWidget(btn,1,1); - - btn = new QPushButton(__tr2qs_ctx("&Apply","editor"),this); - connect(btn,SIGNAL(clicked()),this,SLOT(applyClicked())); - btn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT))); - g->addWidget(btn,1,2); - - btn = new QPushButton(__tr2qs_ctx("Cancel","editor"),this); - connect(btn,SIGNAL(clicked()),this,SLOT(cancelClicked())); - btn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD))); - g->addWidget(btn,1,3); - - g->setRowStretch(0,1); - g->setColumnStretch(0,1); - setLayout(g); -} - -KviEventEditorWindow::~KviEventEditorWindow() -{ - g_pEventEditorWindow = 0; -} - -void KviEventEditorWindow::okClicked() -{ - m_pEditor->commit(); - close(); -} - -void KviEventEditorWindow::applyClicked() -{ - m_pEditor->commit(); -} - -void KviEventEditorWindow::cancelClicked() -{ - close(); -} - -QPixmap * KviEventEditorWindow::myIconPtr() -{ - return g_pIconManager->getSmallIcon(KVI_SMALLICON_EVENT); -} - -void KviEventEditorWindow::fillCaptionBuffers() -{ - m_szPlainTextCaption = __tr2qs_ctx("Event Editor","editor"); -} - -void KviEventEditorWindow::getConfigGroupName(QString &szName) -{ - szName = "eventeditor"; -} - -void KviEventEditorWindow::saveProperties(KviConfigurationFile *) //cfg -{ -/* -#ifdef COMPILE_SCRIPTTOOLBAR - cfg->writeEntry("Sizes",m_pEditor->sizes()); - cfg->writeEntry("LastEvent",m_pEditor->lastEditedEvent().ptr()); - //qDebug("LAST EDITED=%s",m_pEditor->lastEditedEvent().ptr()); -#endif // COMPILE_SCRIPTTOOLBAR -*/ -} - -void KviEventEditorWindow::loadProperties(KviConfigurationFile *) //cfg -{ -/* -#ifdef COMPILE_SCRIPTTOOLBAR - QValueList def; - def.append(20); - def.append(80); - m_pEditor->setSizes(cfg->readIntListEntry("Sizes",def)); - KviCString tmp = cfg->readEntry("LastEvent",""); - m_pEditor->editEvent(tmp); - //qDebug("LAST EDITED WAS %s",tmp.ptr()); -#endif // COMPILE_SCRIPTTOOLBAR -*/ -} diff --git a/src/modules/eventeditor/eventeditor.h b/src/modules/eventeditor/eventeditor.h deleted file mode 100644 index 1916247da..000000000 --- a/src/modules/eventeditor/eventeditor.h +++ /dev/null @@ -1,136 +0,0 @@ -#ifndef _EVENTEDITOR_H_ -#define _EVENTEDITOR_H_ -//============================================================================= -// -// File : eventeditor.h -// Creation date : Mon Dec 23 2002 20:24:55 CEST by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the linkss of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "KviWindow.h" -#include "KviCString.h" -#include "KviTalPopupMenu.h" - -#include -#include -#include - -class KviScriptEditor; - -class KviEventTreeWidgetItem : public QTreeWidgetItem -{ -public: - unsigned int m_uEventIdx; - QString m_szName; - QString m_szParams; -public: - KviEventTreeWidgetItem(QTreeWidget * par,unsigned int uEvIdx,const QString &name,const QString ¶ms); - ~KviEventTreeWidgetItem() {}; -public: - void setName(const QString &szName); - QString name() const { return m_szName; }; -}; - -class KviEventHandlerTreeWidgetItem : public QTreeWidgetItem -{ -public: - QString m_szName; - QString m_szBuffer; - bool m_bEnabled; - int m_cPos; -public: - KviEventHandlerTreeWidgetItem(QTreeWidgetItem * par,const QString &name,const QString &buffer,bool bEnabled); - ~KviEventHandlerTreeWidgetItem() {}; -public: - const int & cursorPosition(){return m_cPos; }; - void setCursorPosition(const int &cPos){qDebug("set cursor to %d",cPos); m_cPos = cPos; }; - - void setName(const QString &szName); - QString name() const { return m_szName; }; - void setEnabled(const bool bEnabled); -}; - -class KviEventEditorTreeWidget : public QTreeWidget -{ - Q_OBJECT -public: - KviEventEditorTreeWidget(QWidget*); - ~KviEventEditorTreeWidget(){}; -protected: - - void mousePressEvent (QMouseEvent *e); -signals: - void rightButtonPressed(QTreeWidgetItem *,QPoint); -}; - -class KviEventEditor : public QWidget -{ - Q_OBJECT -public: - KviEventEditor(QWidget * par); - ~KviEventEditor(); -public: - KviScriptEditor * m_pEditor; - KviEventEditorTreeWidget * m_pTreeWidget; - QLineEdit * m_pNameEditor; - KviTalPopupMenu * m_pContextPopup; - KviEventHandlerTreeWidgetItem * m_pLastEditedItem; - bool m_bOneTimeSetupDone; -public: - void commit(); - void saveLastEditedItem(); - void getUniqueHandlerName(KviEventTreeWidgetItem *it,QString &buffer); - void getExportEventBuffer(QString &szBuffer,KviEventHandlerTreeWidgetItem * it); -protected slots: - void currentItemChanged(QTreeWidgetItem *it,QTreeWidgetItem *); - void itemPressed(QTreeWidgetItem *it,const QPoint &pnt); - void toggleCurrentHandlerEnabled(); - void removeCurrentHandler(); - void addHandlerForCurrentEvent(); - void exportAllEvents(); - void exportCurrentHandler(); - void eventHandlerDisabled(const QString &szName); -protected: - void showEvent(QShowEvent *e); -private: - void oneTimeSetup(); -}; - -class KviEventEditorWindow : public KviWindow -{ - Q_OBJECT -public: - KviEventEditorWindow(KviMainWindow * lpFrm); - ~KviEventEditorWindow(); -protected: - KviEventEditor * m_pEditor; -protected: - virtual QPixmap * myIconPtr(); - virtual void fillCaptionBuffers(); - virtual void getConfigGroupName(QString &szName); - virtual void saveProperties(KviConfigurationFile *); - virtual void loadProperties(KviConfigurationFile *); -protected slots: - void cancelClicked(); - void okClicked(); - void applyClicked(); -}; - -#endif //_EVENTEDITOR_H_ diff --git a/src/modules/eventeditor/libkvieventeditor.cpp b/src/modules/eventeditor/libkvieventeditor.cpp index 61fce5f16..5f69b618f 100644 --- a/src/modules/eventeditor/libkvieventeditor.cpp +++ b/src/modules/eventeditor/libkvieventeditor.cpp @@ -22,13 +22,13 @@ // //============================================================================= -#include "eventeditor.h" +#include "EventEditorWindow.h" #include "KviModule.h" #include "KviLocale.h" #include "KviMainWindow.h" -KviEventEditorWindow * g_pEventEditorWindow = 0; +EventEditorWindow * g_pEventEditorWindow = 0; /* @@ -49,7 +49,7 @@ static bool eventeditor_kvs_cmd_open(KviKvsModuleCommandCall * c) { if(!g_pEventEditorWindow) { - g_pEventEditorWindow = new KviEventEditorWindow(c->window()->frame()); + g_pEventEditorWindow = new EventEditorWindow(c->window()->frame()); c->window()->frame()->addWindow(g_pEventEditorWindow); } diff --git a/src/modules/filetransferwindow/CMakeLists.txt b/src/modules/filetransferwindow/CMakeLists.txt index 1a1da2d39..bc408b8dc 100644 --- a/src/modules/filetransferwindow/CMakeLists.txt +++ b/src/modules/filetransferwindow/CMakeLists.txt @@ -3,12 +3,12 @@ SUBDIRS(caps) SET(kvifiletransferwindow_MOC_HDRS - filetransferwindow.h + FileTransferWindow.h ) SET(kvifiletransferwindow_SRCS libkvifiletransferwindow.cpp - filetransferwindow.cpp + FileTransferWindow.cpp ) # After this call, files will be moc'ed to moc_kvi_*.cpp diff --git a/src/modules/filetransferwindow/FileTransferWindow.cpp b/src/modules/filetransferwindow/FileTransferWindow.cpp new file mode 100644 index 000000000..a4bd25cce --- /dev/null +++ b/src/modules/filetransferwindow/FileTransferWindow.cpp @@ -0,0 +1,866 @@ +//============================================================================= +// +// File : FileTransferWindow.cpp +// Creation date : Mon Apr 21 2003 23:14:12 CEST by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2003-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the linkss of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "FileTransferWindow.h" + +#include "kvi_debug.h" +#include "KviIconManager.h" +#include "KviIrcView.h" +#include "kvi_out.h" +#include "KviOptions.h" +#include "KviLocale.h" +#include "kvi_out.h" +#include "KviMircCntrl.h" +#include "KviThemedLabel.h" +#include "KviInput.h" +#include "KviQString.h" +#include "KviTalHBox.h" +#include "KviMainWindow.h" +#include "KviMdiManager.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef COMPILE_KDE_SUPPORT + #include + #include + #include + #include + #include +#endif //COMPILE_KDE_SUPPORT + +#ifdef COMPILE_PSEUDO_TRANSPARENCY + extern KVIRC_API QPixmap * g_pShadedChildGlobalDesktopBackground; +#endif + +#define FILETRANSFERW_CELLSIZE 70 + +extern FileTransferWindow * g_pFileTransferWindow; + + +FileTransferItem::FileTransferItem(FileTransferWidget * v,KviFileTransfer * t) +: KviTalTableWidgetItemEx(v) +{ + m_pTransfer = t; + m_pTransfer->setDisplayItem(this); + + //create items for the second and the third column + col1Item = new KviTalTableWidgetItem(v, row(), 1); + col2Item = new KviTalTableWidgetItem(v, row(), 2); + //FIXME fixed row height + tableWidget()->setRowHeight( row(), FILETRANSFERW_CELLSIZE ); +} + +FileTransferItem::~FileTransferItem() +{ + m_pTransfer->setDisplayItem(0); + delete col1Item; + delete col2Item; +} + +void FileTransferItem::displayUpdate() +{ + //FIXME this hurts + int dummy = (int) time(NULL); + tableWidget()->model()->setData(tableWidget()->model()->index(row(),0), dummy, Qt::DisplayRole); + tableWidget()->model()->setData(tableWidget()->model()->index(row(),1), dummy, Qt::DisplayRole); + tableWidget()->model()->setData(tableWidget()->model()->index(row(),2), dummy, Qt::DisplayRole); +} + +QString FileTransferItem::key(int,bool) const +{ + QString ret; + ret.setNum(m_pTransfer->id()); + if(ret.length() == 1)ret.prepend("0000000"); + else if(ret.length() == 2)ret.prepend("000000"); + else if(ret.length() == 3)ret.prepend("00000"); + else if(ret.length() == 4)ret.prepend("0000"); + else if(ret.length() == 5)ret.prepend("000"); + else if(ret.length() == 6)ret.prepend("00"); + else if(ret.length() == 7)ret.prepend("0"); + return ret; +} + + + +FileTransferWidget::FileTransferWidget(QWidget * pParent) +: KviTalTableWidget(pParent) +{ + //hide the header + verticalHeader()->hide(); + //hide cells grids + setShowGrid(false); + //disable cell content editing + setEditTriggers(QAbstractItemView::NoEditTriggers); + + //select one row at once + setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::SingleSelection); + + //prepare columns + setColumnCount(3); + + QStringList colHeaders; + colHeaders << __tr2qs_ctx("Type","filetransferwindow") + << __tr2qs_ctx("Information","filetransferwindow") + << __tr2qs_ctx("Progress","filetransferwindow"); + setHorizontalHeaderLabels(colHeaders); + //default column widths + setColumnWidth(0, FILETRANSFERW_CELLSIZE); + horizontalHeader()->setResizeMode(0, QHeaderView::Fixed); + horizontalHeader()->setResizeMode(1, QHeaderView::Interactive); + setColumnWidth(1, 500); + horizontalHeader()->setStretchLastSection(true); + //focus policy + setFocusPolicy(Qt::NoFocus); + viewport()->setFocusPolicy(Qt::NoFocus); +} + +void FileTransferWidget::mousePressEvent (QMouseEvent *e) +{ + if (e->button() == Qt::RightButton) + { + // we have 3 items: the one on the first column is the real one (has a transfer() member) + // others are just fakes + QTableWidgetItem *clicked = itemAt(e->pos()); + if(clicked) + { + FileTransferItem *i = (FileTransferItem*) item(clicked->row(),0); + if (i) emit rightButtonPressed(i, QCursor::pos()); + } + } + QTableWidget::mousePressEvent(e); +} + +void FileTransferWidget::mouseDoubleClickEvent (QMouseEvent *e) +{ + // we have 3 items: the one on the first column is the real one (has a transfer() member) + // others are just fakes + QTableWidgetItem *clicked = itemAt(e->pos()); + if(clicked) + { + FileTransferItem *i = (FileTransferItem*) item(clicked->row(),0); + if (i) emit doubleClicked(i,QCursor::pos()); + } + QTableWidget::mouseDoubleClickEvent(e); +} + +void FileTransferWidget::paintEvent(QPaintEvent * event) +{ + QPainter *p = new QPainter(viewport()); + QStyleOptionViewItem option = viewOptions(); + QRect rect = event->rect(); + +#ifdef COMPILE_PSEUDO_TRANSPARENCY + if(KVI_OPTION_BOOL(KviOption_boolUseCompositingForTransparency) && g_pApp->supportsCompositing()) + { + p->save(); + p->setCompositionMode(QPainter::CompositionMode_Source); + QColor col=KVI_OPTION_COLOR(KviOption_colorGlobalTransparencyFade); + col.setAlphaF((float)((float)KVI_OPTION_UINT(KviOption_uintGlobalTransparencyChildFadeFactor) / (float)100)); + p->fillRect(rect, col); + p->restore(); + } else if(g_pShadedChildGlobalDesktopBackground) + { + QPoint pnt = g_pFileTransferWindow->mdiParent() ? viewport()->mapTo(g_pFrame, rect.topLeft() + g_pFrame->mdiManager()->scrollBarsOffset()) : viewport()->mapTo(g_pFileTransferWindow, rect.topLeft()); + p->drawTiledPixmap(rect,*(g_pShadedChildGlobalDesktopBackground), pnt); + } else { +#endif + //FIXME this is not the treewindowlist + p->fillRect(rect,KVI_OPTION_COLOR(KviOption_colorTreeWindowListBackground)); +#ifdef COMPILE_PSEUDO_TRANSPARENCY + } +#endif + delete p; + + //call paint on all childrens + KviTalTableWidget::paintEvent(event); +} + +void FileTransferItemDelegate::paint(QPainter * p, const QStyleOptionViewItem & option, const QModelIndex & index) const +{ + //FIXME not exactly model/view coding style.. but we need to access data on the item by now + FileTransferWidget* tableWidget = (FileTransferWidget*)parent(); + FileTransferItem* item = (FileTransferItem*) tableWidget->itemFromIndex(index); + + if(!item) return; + KviFileTransfer* transfer = ((FileTransferItem*)tableWidget->item(item->row(), 0))->transfer(); + + + p->setFont(option.font); + + p->setPen(option.state & QStyle::State_Selected ? option.palette.highlight().color() : option.palette.base().color()); + + p->drawRect(option.rect); + p->setPen(transfer->active() ? QColor(180,180,180) : QColor(200,200,200)); + + p->drawRect(option.rect.left() + 1, option.rect.top() + 1, option.rect.width() - 2,option.rect.height() - 2); + p->fillRect(option.rect.left() + 2, option.rect.top() + 2, option.rect.width() - 4, option.rect.height() - 4,transfer->active() ? QColor(240,240,240) : QColor(225,225,225)); + + transfer->displayPaint(p, index.column(), option.rect); +} + +QSize FileTransferItemDelegate::sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const +{ + // FIXME fixed width + return QSize(((FileTransferWidget*)parent())->viewport()->size().width(), 68); +} + +FileTransferWindow::FileTransferWindow(KviModuleExtensionDescriptor * d,KviMainWindow * lpFrm) +: KviWindow(KVI_WINDOW_TYPE_TOOL,lpFrm,"file transfer window",0), KviModuleExtension(d) +{ + g_pFileTransferWindow = this; + setAutoFillBackground(false); + + m_pContextPopup = 0; + m_pLocalFilePopup = 0; + m_pOpenFilePopup = 0; + + m_pTimer = new QTimer(this); + connect(m_pTimer,SIGNAL(timeout()),this,SLOT(heartbeat())); + + m_pSplitter = new KviTalSplitter(Qt::Horizontal,this); + m_pSplitter->setObjectName("transferwindow_hsplitter"); + m_pSplitter->setChildrenCollapsible(false); + + m_pVertSplitter = new KviTalSplitter(Qt::Vertical,m_pSplitter); + m_pVertSplitter->setObjectName("transferwindow_vsplitter"); + m_pVertSplitter->setChildrenCollapsible(false); + + m_pTableWidget = new FileTransferWidget(m_pVertSplitter); + + //ad-hoc itemdelegate for this view + m_pItemDelegate = new FileTransferItemDelegate(m_pTableWidget); + m_pTableWidget->setItemDelegate(m_pItemDelegate); + +/* + * TODO + KviDynamicToolTip * tp = new KviDynamicToolTip(m_pTableWidget->viewport()); + connect(tp,SIGNAL(tipRequest(KviDynamicToolTip *,const QPoint &)),this,SLOT(tipRequest(KviDynamicToolTip *,const QPoint &))); +*/ + + QFontMetrics fm(font()); + m_iLineSpacing = fm.lineSpacing(); + + m_pIrcView = new KviIrcView(m_pVertSplitter,lpFrm,this); + + m_pTableWidget->installEventFilter(this); + + connect(m_pTableWidget,SIGNAL(rightButtonPressed(FileTransferItem *,QPoint)), + this,SLOT(rightButtonPressed(FileTransferItem *,QPoint))); + connect(m_pTableWidget,SIGNAL(doubleClicked(FileTransferItem *,const QPoint &)),this,SLOT(doubleClicked(FileTransferItem *,const QPoint &))); + fillTransferView(); + + connect(KviFileTransferManager::instance(),SIGNAL(transferRegistered(KviFileTransfer *)),this,SLOT(transferRegistered(KviFileTransfer *))); + connect(KviFileTransferManager::instance(),SIGNAL(transferUnregistering(KviFileTransfer *)),this,SLOT(transferUnregistering(KviFileTransfer *))); + + KviFileTransferManager::instance()->setTransferWindow(this); + + m_pTimer->start(2000); +} + +FileTransferWindow::~FileTransferWindow() +{ + KviFileTransferManager::instance()->setTransferWindow(0); + g_pFileTransferWindow = 0; +} + +bool FileTransferWindow::eventFilter( QObject *obj, QEvent *ev ) +{ + if( ( ev->type() == QEvent::KeyPress ) ) + { + //m_pTableWidget could not have been initialized yet when FileTransferWindow + //will receive the first events.. but it will surely be on a keypress event + if(obj==m_pTableWidget) + { + QKeyEvent *keyEvent = (QKeyEvent*)ev; + switch(keyEvent->key()) + { + case Qt::Key_Delete: + if(m_pTableWidget->currentItem()) + { + delete m_pTableWidget->currentItem(); + return TRUE; + } + break; + } + } + } + return KviWindow::eventFilter( obj, ev ); +} + +void FileTransferWindow::fontChange(const QFont &oldFont) +{ + QFontMetrics fm(font()); + m_iLineSpacing = fm.lineSpacing(); + KviWindow::fontChange(oldFont); +} + +void FileTransferWindow::tipRequest(KviDynamicToolTip * tip,const QPoint &pnt) +{ + FileTransferItem * it = (FileTransferItem *)m_pTableWidget->itemAt(pnt); + if(!it)return; + QString txt = it->transfer()->tipText(); + tip->tip(m_pTableWidget->visualItemRect(it),txt); +} + +void FileTransferWindow::fillTransferView() +{ + KviPointerList * l = KviFileTransferManager::instance()->transferList(); + if(!l)return; + FileTransferItem * it; + for(KviFileTransfer * t = l->first();t;t = l->next()) + { + it = new FileTransferItem(m_pTableWidget,t); + t->setDisplayItem(it); + } +} + +FileTransferItem * FileTransferWindow::findItem(KviFileTransfer * t) +{ + int i; + FileTransferItem * it; + + for(i=0;irowCount();i++) + { + it = (FileTransferItem *)m_pTableWidget->item(i,0); + if(!it) continue; + + if(it->transfer() == t) + return it; + } + return 0; +} + +void FileTransferWindow::transferRegistered(KviFileTransfer * t) +{ + new FileTransferItem(m_pTableWidget,t); + //t->setDisplayItem(it); +} + +void FileTransferWindow::transferUnregistering(KviFileTransfer * t) +{ + FileTransferItem * it = findItem(t); + //t->setDisplayItem(0); + if(it) + { + delete it; + it = 0; + } +} + +void FileTransferWindow::doubleClicked(FileTransferItem *it,const QPoint &) +{ + if(it) openLocalFile(); +} + +void FileTransferWindow::rightButtonPressed(FileTransferItem *it,const QPoint &pnt) +{ + if(!m_pContextPopup)m_pContextPopup = new KviTalPopupMenu(this); + if(!m_pLocalFilePopup)m_pLocalFilePopup = new KviTalPopupMenu(this); + if(!m_pOpenFilePopup) + { + m_pOpenFilePopup= new KviTalPopupMenu(this); + connect(m_pOpenFilePopup,SIGNAL(activated(int)),this,SLOT(openFilePopupActivated(int))); + } + + m_pContextPopup->clear(); + + int id; + + if(it) + { + FileTransferItem * i = (FileTransferItem *)it; + if(i->transfer()) + { + + QString szFile = i->transfer()->localFileName(); + if(!szFile.isEmpty()) + { + m_pLocalFilePopup->clear(); + + QString tmp = "file:/"; + tmp += szFile; + tmp += "
"; + + QFileInfo fi(szFile); + if(fi.exists()) + { + tmp += ""; + tmp += __tr2qs_ctx("Size: %1","filetransferwindow").arg(KviQString::makeSizeReadable(fi.size())); + tmp += "
"; + } + +#ifdef COMPILE_KDE_SUPPORT + tmp += "Mime: "; + tmp += KMimeType::findByPath(szFile)->name(); + tmp += ""; +#endif //COMPILE_KDE_SUPPORT + + QLabel * l = new QLabel(tmp,m_pLocalFilePopup); + QPalette p; + l->setStyleSheet("background-color: " + p.color(QPalette::Normal, QPalette::Mid).name()); + m_pLocalFilePopup->insertItem(l); + +#ifdef COMPILE_KDE_SUPPORT + QString mimetype = KMimeType::findByPath(szFile)->name(); + KService::List offers = KMimeTypeTrader::self()->query(mimetype,"Application"); + + id = m_pLocalFilePopup->insertItem(__tr2qs_ctx("&Open","filetransferwindow"),this,SLOT(openLocalFile())); + m_pLocalFilePopup->setItemParameter(id,-1); + + m_pOpenFilePopup->clear(); + + int id; + int idx = 0; + + for(KService::List::Iterator itOffers = offers.begin(); + itOffers != offers.end(); ++itOffers) + { + id = m_pOpenFilePopup->insertItem( + SmallIcon((*itOffers).data()->icon()), + (*itOffers).data()->name() + ); + m_pOpenFilePopup->setItemParameter(id,idx); + idx++; + } + + m_pOpenFilePopup->insertSeparator(); + + id = m_pOpenFilePopup->insertItem(__tr2qs_ctx("&Other...","filetransferwindow"),this,SLOT(openLocalFileWith())); + m_pOpenFilePopup->setItemParameter(id,-1); + + m_pLocalFilePopup->insertItem(__tr2qs_ctx("Open &With","filetransferwindow"),m_pOpenFilePopup); + m_pLocalFilePopup->insertSeparator(); + m_pLocalFilePopup->insertItem(__tr2qs_ctx("Open &Location","filetransferwindow"),this,SLOT(openLocalFileFolder())); + m_pLocalFilePopup->insertItem(__tr2qs_ctx("Terminal at Location","filetransferwindow"),this,SLOT(openLocalFileTerminal())); + m_pLocalFilePopup->insertSeparator(); +#endif //COMPILE_KDE_SUPPORT + +//-| Grifisx & Noldor |- +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + id = m_pLocalFilePopup->insertItem(__tr2qs_ctx("&Open","filetransferwindow"),this,SLOT(openLocalFile())); + m_pLocalFilePopup->setItemParameter(id,-1); + m_pOpenFilePopup->insertSeparator(); + m_pLocalFilePopup->insertItem(__tr2qs_ctx("Open &With","filetransferwindow"),this,SLOT(openLocalFileWith())); + m_pLocalFilePopup->insertSeparator(); + m_pLocalFilePopup->insertItem(__tr2qs_ctx("Open &Location","filetransferwindow"),this,SLOT(openLocalFileFolder())); + m_pLocalFilePopup->insertItem(__tr2qs_ctx("MS-DOS Prompt at Location","filetransferwindow"),this,SLOT(openLocalFileTerminal())); + m_pLocalFilePopup->insertSeparator(); +#endif +// G&N end + + m_pLocalFilePopup->insertItem(__tr2qs_ctx("&Copy Path to Clipboard","filetransferwindow"),this,SLOT(copyLocalFileToClipboard())); + + id = m_pLocalFilePopup->insertItem(__tr2qs_ctx("&Delete file","filetransferwindow"),this,SLOT(deleteLocalFile())); + m_pLocalFilePopup->setItemEnabled(id,i->transfer()->terminated()); + m_pContextPopup->insertItem(__tr2qs_ctx("Local &File","filetransferwindow"),m_pLocalFilePopup); + + + } + + i->transfer()->fillContextPopup(m_pContextPopup); + m_pContextPopup->insertSeparator(); + } + } + + + bool bHaveTerminated = false; + int i; + FileTransferItem * item; + + for(i=0;irowCount();i++) + { + item = (FileTransferItem *)m_pTableWidget->item(i,0); + if(!item) + continue; + + if(item->transfer()->terminated()) + { + bHaveTerminated = true; + break; + } + } + + id = m_pContextPopup->insertItem(__tr2qs_ctx("&Clear Terminated","filetransferwindow"),this,SLOT(clearTerminated())); + m_pContextPopup->setItemEnabled(id,bHaveTerminated); + + bool bAreTransfersActive = false; + if(m_pTableWidget->rowCount() >= 1) + bAreTransfersActive = true; + + id = m_pContextPopup->insertItem(__tr2qs_ctx("Clear &All","filetransferwindow"),this,SLOT(clearAll())); + m_pContextPopup->setItemEnabled(id,bAreTransfersActive); + + m_pContextPopup->popup(pnt); +} + + +KviFileTransfer * FileTransferWindow::selectedTransfer() +{ + if(m_pTableWidget->selectedItems().count() == 0) return 0; + FileTransferItem * it = (FileTransferItem *)m_pTableWidget->selectedItems().first(); + if(!it)return 0; + FileTransferItem * i = (FileTransferItem *)it; + return i->transfer(); +} + +void FileTransferWindow::openFilePopupActivated(int id) +{ +#ifdef COMPILE_KDE_SUPPORT + int ip = m_pOpenFilePopup->itemParameter(id); + if(ip < 0)return; + + KviFileTransfer * t = selectedTransfer(); + if(!t)return; + QString tmp = t->localFileName(); + if(tmp.isEmpty())return; + + + QString mimetype = KMimeType::findByPath(tmp)->name(); + KService::List offers = KMimeTypeTrader::self()->query(mimetype,"Application"); + + int idx = 0; + for(KService::List::Iterator itOffers = offers.begin(); + itOffers != offers.end(); ++itOffers) + { + if(idx == ip) + { + KUrl::List lst; + KUrl url; + url.setPath(tmp); + lst.append(url); + KRun::run(*((*itOffers).data()),lst,g_pFrame); + break; + } + idx++; + } +#endif //COMPILE_KDE_SUPPORT +} + +void FileTransferWindow::openLocalFileTerminal() +{ +//-| Grifisx & Noldor |- +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + KviFileTransfer * t = selectedTransfer(); + if(!t)return; + QString tmp = t->localFileName(); + if(tmp.isEmpty())return; + int idx = tmp.lastIndexOf("/"); + if(idx == -1)return; + tmp = tmp.left(idx); + tmp.append("\""); + // FIXME: this is not a solution ...because if the drive isn't system's drive the command 'cd' naturaly doesn't work + tmp.prepend("cmd.exe /k cd \""); + system(tmp.toLocal8Bit().data()); +#else +// G&N end + #ifdef COMPILE_KDE_SUPPORT + KviFileTransfer * t = selectedTransfer(); + if(!t)return; + QString tmp = t->localFileName(); + if(tmp.isEmpty())return; + + int idx = tmp.lastIndexOf("/"); + if(idx == -1)return; + tmp = tmp.left(idx); + + tmp.prepend("konsole --workdir=\""); + tmp.append("\""); + + KRun::runCommand(tmp,g_pFrame); + #endif //COMPILE_KDE_SUPPORT +#endif +} + +void FileTransferWindow::deleteLocalFile() +{ + KviFileTransfer * t = selectedTransfer(); + if(!t)return; + + QString fName = t->localFileName(); + QString tmp; + + KviQString::sprintf(tmp,__tr2qs_ctx("Do you really want to delete the file %Q?","filetransferwindow"),&fName); + + if(QMessageBox::warning(this,__tr2qs_ctx("Confirm delete","filetransferwindow"), + tmp,__tr2qs_ctx("Yes","filetransferwindow"),__tr2qs_ctx("No","filetransferwindow")) != 0) + return; + + if(!QFile::remove(fName)) + QMessageBox::warning(this,__tr2qs_ctx("Delete failed","filetransferwindow"), + __tr2qs_ctx("Failed to remove the file","filetransferwindow"), + __tr2qs_ctx("OK","filetransferwindow")); +} + +void FileTransferWindow::openLocalFile() +{ +//-| Grifisx & Noldor |- +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + + KviFileTransfer * t = selectedTransfer(); + if(!t)return; + QString tmp = t->localFileName(); + if(tmp.isEmpty())return; + tmp.replace("/","\\"); + ShellExecute(0,"open",tmp.toLocal8Bit().data(),NULL,NULL,SW_SHOWNORMAL); //You have to link the shell32.lib +#else +// G&N end + #ifdef COMPILE_KDE_SUPPORT + KviFileTransfer * t = selectedTransfer(); + if(!t)return; + QString tmp = t->localFileName(); + if(tmp.isEmpty())return; + + QString mimetype = KMimeType::findByPath(tmp)->name(); //KMimeType + KService::Ptr offer = KMimeTypeTrader::self()->preferredService(mimetype,"Application"); + if(!offer) + { + openLocalFileWith(); + return; + } + + KUrl::List lst; + KUrl url; + url.setPath(tmp); + lst.append(url); + + KRun::run(*offer, lst, g_pFrame); + #endif //COMPILE_KDE_SUPPORT +#endif +} + +void FileTransferWindow::openLocalFileWith() +{ +//-| Grifisx & Noldor |- +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + KviFileTransfer * t = selectedTransfer(); + if(!t)return; + QString tmp = t->localFileName(); + if(tmp.isEmpty())return; + tmp.replace("/","\\"); + tmp.prepend("rundll32.exe shell32.dll,OpenAs_RunDLL "); // this if to show the 'open with...' window + WinExec(tmp.toLocal8Bit().data(),SW_SHOWNORMAL); +#else +// G&N end + #ifdef COMPILE_KDE_SUPPORT + KviFileTransfer * t = selectedTransfer(); + if(!t)return; + QString tmp = t->localFileName(); + if(tmp.isEmpty())return; + + KUrl::List lst; + KUrl url; + url.setPath(tmp); + lst.append(url); + KRun::displayOpenWithDialog(lst,g_pFrame); + #endif //COMPILE_KDE_SUPPORT +#endif +} + +void FileTransferWindow::copyLocalFileToClipboard() +{ + KviFileTransfer * t = selectedTransfer(); + if(!t)return; + QString tmp = t->localFileName(); + if(tmp.isEmpty())return; + QApplication::clipboard()->setText(tmp); +} + +void FileTransferWindow::openLocalFileFolder() +{ +//-| Grifisx & Noldor|- +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + KviFileTransfer * t = selectedTransfer(); + if(!t)return; + QString tmp = t->localFileName(); + if(tmp.isEmpty())return; + tmp=QFileInfo(tmp).absolutePath(); + tmp.replace('/','\\'); + tmp.prepend("explorer.exe "); + WinExec(tmp.toLocal8Bit().data(), SW_MAXIMIZE); +#else +// G&N end + #ifdef COMPILE_KDE_SUPPORT + KviFileTransfer * t = selectedTransfer(); + if(!t)return; + QString tmp = t->localFileName(); + if(tmp.isEmpty())return; + + int idx = tmp.lastIndexOf("/"); + if(idx == -1)return; + tmp = tmp.left(idx); + + QString mimetype = KMimeType::findByPath(tmp)->name(); // inode/directory + KService::Ptr offer = KMimeTypeTrader::self()->preferredService(mimetype,"Application"); + if(!offer)return; + + KUrl::List lst; + KUrl url; + url.setPath(tmp); + lst.append(url); + KRun::run(*offer,lst,g_pFrame); + #endif //COMPILE_KDE_SUPPORT +#endif +} + +void FileTransferWindow::heartbeat() +{ + int i; + QModelIndex index; + FileTransferItem* it; + int dummy = (int) time(NULL); + + for(i=0;i<=m_pTableWidget->rowCount();i++) + { + it = (FileTransferItem *)m_pTableWidget->item(i,0); + + if(!it) + continue; + + if(it->transfer()->active()) + { + m_pTableWidget->model()->setData(m_pTableWidget->model()->index(i,0), dummy, Qt::DisplayRole); + m_pTableWidget->model()->setData(m_pTableWidget->model()->index(i,1), dummy, Qt::DisplayRole); + m_pTableWidget->model()->setData(m_pTableWidget->model()->index(i,2), dummy, Qt::DisplayRole); + } + } +} + +void FileTransferWindow::clearAll() +{ + QString tmp; + + bool bHaveAllTerminated = true; + int i; + FileTransferItem * item; + + for(i=0;irowCount();i++) + { + item = (FileTransferItem *)m_pTableWidget->item(i,0); + if(!item) + continue; + + if(!item->transfer()->terminated()) + { + bHaveAllTerminated = false; + break; + } + } + + KviQString::sprintf(tmp,__tr2qs_ctx("Clear all transfers, including any in progress?","filetransferwindow")); + + // If any transfer is active asks for confirm + if(!bHaveAllTerminated) + if(QMessageBox::warning(this,__tr2qs_ctx("Clear All Transfers? - KVIrc","filetransferwindow"), tmp,__tr2qs_ctx("Yes","filetransferwindow"),__tr2qs_ctx("No","filetransferwindow")) != 0) + return; + + KviFileTransferManager::instance()->killAllTransfers(); +} + +void FileTransferWindow::clearTerminated() +{ + KviFileTransferManager::instance()->killTerminatedTransfers(); +} + +void FileTransferWindow::getBaseLogFileName(QString &buffer) +{ + buffer.sprintf("FILETRANSFER"); +} + +QPixmap * FileTransferWindow::myIconPtr() +{ + return g_pIconManager->getSmallIcon(KVI_SMALLICON_FILETRANSFER); +} + +void FileTransferWindow::resizeEvent(QResizeEvent *) +{ + m_pSplitter->setGeometry(0,0,width(),height()); +} + +QSize FileTransferWindow::sizeHint() const +{ + return m_pSplitter->sizeHint(); +} + +void FileTransferWindow::fillCaptionBuffers() +{ + m_szPlainTextCaption = __tr2qs_ctx("File Transfers","filetransferwindow"); +} + +void FileTransferWindow::die() +{ + close(); +} + + + +//#warning "Load & save properties of this kind of window" + +//void FileTransferWindow::saveProperties() +//{ +// KviWindowProperty p; +// p.rect = externalGeometry(); +// p.isDocked = isAttacched(); +// QValueList l(m_pSplitter->sizes()); +// if(l.count() >= 1)p.splitWidth1 = *(l.at(0)); +// if(l.count() >= 2)p.splitWidth2 = *(l.at(1)); +// p.timestamp = m_pView->timestamp(); +// p.imagesVisible = m_pView->imagesVisible(); +// p.isMaximized = isAttacched() && isMaximized(); +// p.topSplitWidth1 = 0; +// p.topSplitWidth2 = 0; +// p.topSplitWidth3 = 0; +// g_pOptions->m_pWinPropertiesList->setProperty(caption(),&p); +//} +// +//void FileTransferWindow::setProperties(KviWindowProperty *p) +//{ +// QValueList l; +// l.append(p->splitWidth1); +// l.append(p->splitWidth2); +// m_pVertSplitter->setSizes(l); +// m_pIrcView->setTimestamp(p->timestamp); +// m_pIrcView->setShowImages(p->imagesVisible); +//} + +void FileTransferWindow::applyOptions() +{ + m_pIrcView->applyOptions(); + KviWindow::applyOptions(); +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_FileTransferWindow.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/filetransferwindow/FileTransferWindow.h b/src/modules/filetransferwindow/FileTransferWindow.h new file mode 100644 index 000000000..2fcac8689 --- /dev/null +++ b/src/modules/filetransferwindow/FileTransferWindow.h @@ -0,0 +1,139 @@ +#ifndef _FILETRANSFERWINDOW_H_ +#define _FILETRANSFERWINDOW_H_ +//============================================================================= +// +// File : FileTransferWindow.h +// Creation date : Mon Apr 21 2003 23:14:12 CEST by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2003-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the linkss of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviWindow.h" +#include "KviCString.h" +#include "KviIrcSocket.h" +#include "KviIrcServerParser.h" +#include "KviConsoleWindow.h" +#include "KviModuleExtension.h" +#include "KviFileTransfer.h" +#include "KviDynamicToolTip.h" +#include "KviTalTableWidget.h" +#include "KviTalPopupMenu.h" +#include "KviTalIconAndRichTextItemDelegate.h" + +#include +#include + +class FileTransferItem; + +class FileTransferWidget : public KviTalTableWidget +{ + friend class FileTransferItemDelegate; + Q_OBJECT + Q_PROPERTY(int TransparencyCapable READ dummyRead) +public: + FileTransferWidget(QWidget * pParent); + ~FileTransferWidget() {}; + void paintEvent(QPaintEvent * event); + int dummyRead() const { return 0; }; +protected: + void mousePressEvent (QMouseEvent *e); + void mouseDoubleClickEvent (QMouseEvent *e); +signals: + void rightButtonPressed(FileTransferItem *,QPoint pnt); + void doubleClicked(FileTransferItem *,QPoint pnt); +}; + +class FileTransferItem : public KviTalTableWidgetItemEx +{ +public: + FileTransferItem(FileTransferWidget * v,KviFileTransfer * t); + ~FileTransferItem(); +protected: + KviFileTransfer * m_pTransfer; + KviTalTableWidgetItem * col1Item; //item on the second column + KviTalTableWidgetItem * col2Item; //item on the third column +public: + KviFileTransfer * transfer(){ return m_pTransfer; }; + virtual QString key(int column,bool bAcending) const; + virtual void displayUpdate(); +}; + +class FileTransferItemDelegate : public KviTalIconAndRichTextItemDelegate +{ + Q_OBJECT +public: + FileTransferItemDelegate(QAbstractItemView * pWidget=0) + : KviTalIconAndRichTextItemDelegate(pWidget) {}; + ~FileTransferItemDelegate(){}; + QSize sizeHint(const QStyleOptionViewItem &option,const QModelIndex &index) const; + void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const; +}; + +class FileTransferWindow : public KviWindow, public KviModuleExtension +{ + friend class FileTransferItem; + friend class FileTransferItemDelegate; + Q_OBJECT +public: + FileTransferWindow(KviModuleExtensionDescriptor * d,KviMainWindow * lpFrm); + ~FileTransferWindow(); +protected: + QSplitter * m_pVertSplitter; + FileTransferWidget * m_pTableWidget; + QAbstractItemDelegate * m_pItemDelegate; + KviTalPopupMenu * m_pContextPopup; + KviTalPopupMenu * m_pLocalFilePopup; + KviTalPopupMenu * m_pOpenFilePopup; + QTimer * m_pTimer; + int m_iLineSpacing; // cached fm value +public: // Methods + virtual void die(); +protected: + virtual QPixmap * myIconPtr(); + virtual void fillCaptionBuffers(); + virtual void applyOptions(); + virtual void resizeEvent(QResizeEvent *e); + virtual void getBaseLogFileName(QString &buffer); + FileTransferItem * findItem(KviFileTransfer * t); + void fillTransferView(); + KviFileTransfer * selectedTransfer(); + virtual void fontChange(const QFont &oldFont); + bool eventFilter( QObject *obj, QEvent *ev ); +public: + virtual QSize sizeHint() const; + int lineSpacing(){ return m_iLineSpacing; }; +protected slots: + void transferRegistered(KviFileTransfer *t); + void transferUnregistering(KviFileTransfer *t); + void rightButtonPressed(FileTransferItem *it,const QPoint &pnt); + void doubleClicked(FileTransferItem *it,const QPoint &pnt); + void heartbeat(); + void clearTerminated(); + void clearAll(); + void tipRequest(KviDynamicToolTip * tip,const QPoint &pnt); + void openLocalFile(); + void openLocalFileWith(); + void copyLocalFileToClipboard(); + void openLocalFileFolder(); + void openFilePopupActivated(int id); + void openLocalFileTerminal(); + void deleteLocalFile(); +}; + +#endif //_FILETRANSFERWINDOW_H_ diff --git a/src/modules/filetransferwindow/filetransferwindow.cpp b/src/modules/filetransferwindow/filetransferwindow.cpp deleted file mode 100644 index 1ef3b0bad..000000000 --- a/src/modules/filetransferwindow/filetransferwindow.cpp +++ /dev/null @@ -1,866 +0,0 @@ -//============================================================================= -// -// File : filetransferwindow.cpp -// Creation date : Mon Apr 21 2003 23:14:12 CEST by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2003-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the linkss of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "filetransferwindow.h" - -#include "kvi_debug.h" -#include "KviIconManager.h" -#include "KviIrcView.h" -#include "kvi_out.h" -#include "KviOptions.h" -#include "KviLocale.h" -#include "kvi_out.h" -#include "KviMircCntrl.h" -#include "KviThemedLabel.h" -#include "KviInput.h" -#include "KviQString.h" -#include "KviTalHBox.h" -#include "KviMainWindow.h" -#include "KviMdiManager.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef COMPILE_KDE_SUPPORT - #include - #include - #include - #include - #include -#endif //COMPILE_KDE_SUPPORT - -#ifdef COMPILE_PSEUDO_TRANSPARENCY - extern KVIRC_API QPixmap * g_pShadedChildGlobalDesktopBackground; -#endif - -#define FILETRANSFERW_CELLSIZE 70 - -extern KviFileTransferWindow * g_pFileTransferWindow; - - -KviFileTransferItem::KviFileTransferItem(KviFileTransferWidget * v,KviFileTransfer * t) -: KviTalTableWidgetItemEx(v) -{ - m_pTransfer = t; - m_pTransfer->setDisplayItem(this); - - //create items for the second and the third column - col1Item = new KviTalTableWidgetItem(v, row(), 1); - col2Item = new KviTalTableWidgetItem(v, row(), 2); - //FIXME fixed row height - tableWidget()->setRowHeight( row(), FILETRANSFERW_CELLSIZE ); -} - -KviFileTransferItem::~KviFileTransferItem() -{ - m_pTransfer->setDisplayItem(0); - delete col1Item; - delete col2Item; -} - -void KviFileTransferItem::displayUpdate() -{ - //FIXME this hurts - int dummy = (int) time(NULL); - tableWidget()->model()->setData(tableWidget()->model()->index(row(),0), dummy, Qt::DisplayRole); - tableWidget()->model()->setData(tableWidget()->model()->index(row(),1), dummy, Qt::DisplayRole); - tableWidget()->model()->setData(tableWidget()->model()->index(row(),2), dummy, Qt::DisplayRole); -} - -QString KviFileTransferItem::key(int,bool) const -{ - QString ret; - ret.setNum(m_pTransfer->id()); - if(ret.length() == 1)ret.prepend("0000000"); - else if(ret.length() == 2)ret.prepend("000000"); - else if(ret.length() == 3)ret.prepend("00000"); - else if(ret.length() == 4)ret.prepend("0000"); - else if(ret.length() == 5)ret.prepend("000"); - else if(ret.length() == 6)ret.prepend("00"); - else if(ret.length() == 7)ret.prepend("0"); - return ret; -} - - - -KviFileTransferWidget::KviFileTransferWidget(QWidget * pParent) -: KviTalTableWidget(pParent) -{ - //hide the header - verticalHeader()->hide(); - //hide cells grids - setShowGrid(false); - //disable cell content editing - setEditTriggers(QAbstractItemView::NoEditTriggers); - - //select one row at once - setSelectionBehavior(QAbstractItemView::SelectRows); - setSelectionMode(QAbstractItemView::SingleSelection); - - //prepare columns - setColumnCount(3); - - QStringList colHeaders; - colHeaders << __tr2qs_ctx("Type","filetransferwindow") - << __tr2qs_ctx("Information","filetransferwindow") - << __tr2qs_ctx("Progress","filetransferwindow"); - setHorizontalHeaderLabels(colHeaders); - //default column widths - setColumnWidth(0, FILETRANSFERW_CELLSIZE); - horizontalHeader()->setResizeMode(0, QHeaderView::Fixed); - horizontalHeader()->setResizeMode(1, QHeaderView::Interactive); - setColumnWidth(1, 500); - horizontalHeader()->setStretchLastSection(true); - //focus policy - setFocusPolicy(Qt::NoFocus); - viewport()->setFocusPolicy(Qt::NoFocus); -} - -void KviFileTransferWidget::mousePressEvent (QMouseEvent *e) -{ - if (e->button() == Qt::RightButton) - { - // we have 3 items: the one on the first column is the real one (has a transfer() member) - // others are just fakes - QTableWidgetItem *clicked = itemAt(e->pos()); - if(clicked) - { - KviFileTransferItem *i = (KviFileTransferItem*) item(clicked->row(),0); - if (i) emit rightButtonPressed(i, QCursor::pos()); - } - } - QTableWidget::mousePressEvent(e); -} - -void KviFileTransferWidget::mouseDoubleClickEvent (QMouseEvent *e) -{ - // we have 3 items: the one on the first column is the real one (has a transfer() member) - // others are just fakes - QTableWidgetItem *clicked = itemAt(e->pos()); - if(clicked) - { - KviFileTransferItem *i = (KviFileTransferItem*) item(clicked->row(),0); - if (i) emit doubleClicked(i,QCursor::pos()); - } - QTableWidget::mouseDoubleClickEvent(e); -} - -void KviFileTransferWidget::paintEvent(QPaintEvent * event) -{ - QPainter *p = new QPainter(viewport()); - QStyleOptionViewItem option = viewOptions(); - QRect rect = event->rect(); - -#ifdef COMPILE_PSEUDO_TRANSPARENCY - if(KVI_OPTION_BOOL(KviOption_boolUseCompositingForTransparency) && g_pApp->supportsCompositing()) - { - p->save(); - p->setCompositionMode(QPainter::CompositionMode_Source); - QColor col=KVI_OPTION_COLOR(KviOption_colorGlobalTransparencyFade); - col.setAlphaF((float)((float)KVI_OPTION_UINT(KviOption_uintGlobalTransparencyChildFadeFactor) / (float)100)); - p->fillRect(rect, col); - p->restore(); - } else if(g_pShadedChildGlobalDesktopBackground) - { - QPoint pnt = g_pFileTransferWindow->mdiParent() ? viewport()->mapTo(g_pFrame, rect.topLeft() + g_pFrame->mdiManager()->scrollBarsOffset()) : viewport()->mapTo(g_pFileTransferWindow, rect.topLeft()); - p->drawTiledPixmap(rect,*(g_pShadedChildGlobalDesktopBackground), pnt); - } else { -#endif - //FIXME this is not the treewindowlist - p->fillRect(rect,KVI_OPTION_COLOR(KviOption_colorTreeWindowListBackground)); -#ifdef COMPILE_PSEUDO_TRANSPARENCY - } -#endif - delete p; - - //call paint on all childrens - KviTalTableWidget::paintEvent(event); -} - -void KviFileTransferItemDelegate::paint(QPainter * p, const QStyleOptionViewItem & option, const QModelIndex & index) const -{ - //FIXME not exactly model/view coding style.. but we need to access data on the item by now - KviFileTransferWidget* tableWidget = (KviFileTransferWidget*)parent(); - KviFileTransferItem* item = (KviFileTransferItem*) tableWidget->itemFromIndex(index); - - if(!item) return; - KviFileTransfer* transfer = ((KviFileTransferItem*)tableWidget->item(item->row(), 0))->transfer(); - - - p->setFont(option.font); - - p->setPen(option.state & QStyle::State_Selected ? option.palette.highlight().color() : option.palette.base().color()); - - p->drawRect(option.rect); - p->setPen(transfer->active() ? QColor(180,180,180) : QColor(200,200,200)); - - p->drawRect(option.rect.left() + 1, option.rect.top() + 1, option.rect.width() - 2,option.rect.height() - 2); - p->fillRect(option.rect.left() + 2, option.rect.top() + 2, option.rect.width() - 4, option.rect.height() - 4,transfer->active() ? QColor(240,240,240) : QColor(225,225,225)); - - transfer->displayPaint(p, index.column(), option.rect); -} - -QSize KviFileTransferItemDelegate::sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const -{ - // FIXME fixed width - return QSize(((KviFileTransferWidget*)parent())->viewport()->size().width(), 68); -} - -KviFileTransferWindow::KviFileTransferWindow(KviModuleExtensionDescriptor * d,KviMainWindow * lpFrm) -: KviWindow(KVI_WINDOW_TYPE_TOOL,lpFrm,"file transfer window",0), KviModuleExtension(d) -{ - g_pFileTransferWindow = this; - setAutoFillBackground(false); - - m_pContextPopup = 0; - m_pLocalFilePopup = 0; - m_pOpenFilePopup = 0; - - m_pTimer = new QTimer(this); - connect(m_pTimer,SIGNAL(timeout()),this,SLOT(heartbeat())); - - m_pSplitter = new KviTalSplitter(Qt::Horizontal,this); - m_pSplitter->setObjectName("transferwindow_hsplitter"); - m_pSplitter->setChildrenCollapsible(false); - - m_pVertSplitter = new KviTalSplitter(Qt::Vertical,m_pSplitter); - m_pVertSplitter->setObjectName("transferwindow_vsplitter"); - m_pVertSplitter->setChildrenCollapsible(false); - - m_pTableWidget = new KviFileTransferWidget(m_pVertSplitter); - - //ad-hoc itemdelegate for this view - m_pItemDelegate = new KviFileTransferItemDelegate(m_pTableWidget); - m_pTableWidget->setItemDelegate(m_pItemDelegate); - -/* - * TODO - KviDynamicToolTip * tp = new KviDynamicToolTip(m_pTableWidget->viewport()); - connect(tp,SIGNAL(tipRequest(KviDynamicToolTip *,const QPoint &)),this,SLOT(tipRequest(KviDynamicToolTip *,const QPoint &))); -*/ - - QFontMetrics fm(font()); - m_iLineSpacing = fm.lineSpacing(); - - m_pIrcView = new KviIrcView(m_pVertSplitter,lpFrm,this); - - m_pTableWidget->installEventFilter(this); - - connect(m_pTableWidget,SIGNAL(rightButtonPressed(KviFileTransferItem *,QPoint)), - this,SLOT(rightButtonPressed(KviFileTransferItem *,QPoint))); - connect(m_pTableWidget,SIGNAL(doubleClicked(KviFileTransferItem *,const QPoint &)),this,SLOT(doubleClicked(KviFileTransferItem *,const QPoint &))); - fillTransferView(); - - connect(KviFileTransferManager::instance(),SIGNAL(transferRegistered(KviFileTransfer *)),this,SLOT(transferRegistered(KviFileTransfer *))); - connect(KviFileTransferManager::instance(),SIGNAL(transferUnregistering(KviFileTransfer *)),this,SLOT(transferUnregistering(KviFileTransfer *))); - - KviFileTransferManager::instance()->setTransferWindow(this); - - m_pTimer->start(2000); -} - -KviFileTransferWindow::~KviFileTransferWindow() -{ - KviFileTransferManager::instance()->setTransferWindow(0); - g_pFileTransferWindow = 0; -} - -bool KviFileTransferWindow::eventFilter( QObject *obj, QEvent *ev ) -{ - if( ( ev->type() == QEvent::KeyPress ) ) - { - //m_pTableWidget could not have been initialized yet when KviFileTransferWindow - //will receive the first events.. but it will surely be on a keypress event - if(obj==m_pTableWidget) - { - QKeyEvent *keyEvent = (QKeyEvent*)ev; - switch(keyEvent->key()) - { - case Qt::Key_Delete: - if(m_pTableWidget->currentItem()) - { - delete m_pTableWidget->currentItem(); - return TRUE; - } - break; - } - } - } - return KviWindow::eventFilter( obj, ev ); -} - -void KviFileTransferWindow::fontChange(const QFont &oldFont) -{ - QFontMetrics fm(font()); - m_iLineSpacing = fm.lineSpacing(); - KviWindow::fontChange(oldFont); -} - -void KviFileTransferWindow::tipRequest(KviDynamicToolTip * tip,const QPoint &pnt) -{ - KviFileTransferItem * it = (KviFileTransferItem *)m_pTableWidget->itemAt(pnt); - if(!it)return; - QString txt = it->transfer()->tipText(); - tip->tip(m_pTableWidget->visualItemRect(it),txt); -} - -void KviFileTransferWindow::fillTransferView() -{ - KviPointerList * l = KviFileTransferManager::instance()->transferList(); - if(!l)return; - KviFileTransferItem * it; - for(KviFileTransfer * t = l->first();t;t = l->next()) - { - it = new KviFileTransferItem(m_pTableWidget,t); - t->setDisplayItem(it); - } -} - -KviFileTransferItem * KviFileTransferWindow::findItem(KviFileTransfer * t) -{ - int i; - KviFileTransferItem * it; - - for(i=0;irowCount();i++) - { - it = (KviFileTransferItem *)m_pTableWidget->item(i,0); - if(!it) continue; - - if(it->transfer() == t) - return it; - } - return 0; -} - -void KviFileTransferWindow::transferRegistered(KviFileTransfer * t) -{ - new KviFileTransferItem(m_pTableWidget,t); - //t->setDisplayItem(it); -} - -void KviFileTransferWindow::transferUnregistering(KviFileTransfer * t) -{ - KviFileTransferItem * it = findItem(t); - //t->setDisplayItem(0); - if(it) - { - delete it; - it = 0; - } -} - -void KviFileTransferWindow::doubleClicked(KviFileTransferItem *it,const QPoint &) -{ - if(it) openLocalFile(); -} - -void KviFileTransferWindow::rightButtonPressed(KviFileTransferItem *it,const QPoint &pnt) -{ - if(!m_pContextPopup)m_pContextPopup = new KviTalPopupMenu(this); - if(!m_pLocalFilePopup)m_pLocalFilePopup = new KviTalPopupMenu(this); - if(!m_pOpenFilePopup) - { - m_pOpenFilePopup= new KviTalPopupMenu(this); - connect(m_pOpenFilePopup,SIGNAL(activated(int)),this,SLOT(openFilePopupActivated(int))); - } - - m_pContextPopup->clear(); - - int id; - - if(it) - { - KviFileTransferItem * i = (KviFileTransferItem *)it; - if(i->transfer()) - { - - QString szFile = i->transfer()->localFileName(); - if(!szFile.isEmpty()) - { - m_pLocalFilePopup->clear(); - - QString tmp = "file:/"; - tmp += szFile; - tmp += "
"; - - QFileInfo fi(szFile); - if(fi.exists()) - { - tmp += ""; - tmp += __tr2qs_ctx("Size: %1","filetransferwindow").arg(KviQString::makeSizeReadable(fi.size())); - tmp += "
"; - } - -#ifdef COMPILE_KDE_SUPPORT - tmp += "Mime: "; - tmp += KMimeType::findByPath(szFile)->name(); - tmp += ""; -#endif //COMPILE_KDE_SUPPORT - - QLabel * l = new QLabel(tmp,m_pLocalFilePopup); - QPalette p; - l->setStyleSheet("background-color: " + p.color(QPalette::Normal, QPalette::Mid).name()); - m_pLocalFilePopup->insertItem(l); - -#ifdef COMPILE_KDE_SUPPORT - QString mimetype = KMimeType::findByPath(szFile)->name(); - KService::List offers = KMimeTypeTrader::self()->query(mimetype,"Application"); - - id = m_pLocalFilePopup->insertItem(__tr2qs_ctx("&Open","filetransferwindow"),this,SLOT(openLocalFile())); - m_pLocalFilePopup->setItemParameter(id,-1); - - m_pOpenFilePopup->clear(); - - int id; - int idx = 0; - - for(KService::List::Iterator itOffers = offers.begin(); - itOffers != offers.end(); ++itOffers) - { - id = m_pOpenFilePopup->insertItem( - SmallIcon((*itOffers).data()->icon()), - (*itOffers).data()->name() - ); - m_pOpenFilePopup->setItemParameter(id,idx); - idx++; - } - - m_pOpenFilePopup->insertSeparator(); - - id = m_pOpenFilePopup->insertItem(__tr2qs_ctx("&Other...","filetransferwindow"),this,SLOT(openLocalFileWith())); - m_pOpenFilePopup->setItemParameter(id,-1); - - m_pLocalFilePopup->insertItem(__tr2qs_ctx("Open &With","filetransferwindow"),m_pOpenFilePopup); - m_pLocalFilePopup->insertSeparator(); - m_pLocalFilePopup->insertItem(__tr2qs_ctx("Open &Location","filetransferwindow"),this,SLOT(openLocalFileFolder())); - m_pLocalFilePopup->insertItem(__tr2qs_ctx("Terminal at Location","filetransferwindow"),this,SLOT(openLocalFileTerminal())); - m_pLocalFilePopup->insertSeparator(); -#endif //COMPILE_KDE_SUPPORT - -//-| Grifisx & Noldor |- -#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - id = m_pLocalFilePopup->insertItem(__tr2qs_ctx("&Open","filetransferwindow"),this,SLOT(openLocalFile())); - m_pLocalFilePopup->setItemParameter(id,-1); - m_pOpenFilePopup->insertSeparator(); - m_pLocalFilePopup->insertItem(__tr2qs_ctx("Open &With","filetransferwindow"),this,SLOT(openLocalFileWith())); - m_pLocalFilePopup->insertSeparator(); - m_pLocalFilePopup->insertItem(__tr2qs_ctx("Open &Location","filetransferwindow"),this,SLOT(openLocalFileFolder())); - m_pLocalFilePopup->insertItem(__tr2qs_ctx("MS-DOS Prompt at Location","filetransferwindow"),this,SLOT(openLocalFileTerminal())); - m_pLocalFilePopup->insertSeparator(); -#endif -// G&N end - - m_pLocalFilePopup->insertItem(__tr2qs_ctx("&Copy Path to Clipboard","filetransferwindow"),this,SLOT(copyLocalFileToClipboard())); - - id = m_pLocalFilePopup->insertItem(__tr2qs_ctx("&Delete file","filetransferwindow"),this,SLOT(deleteLocalFile())); - m_pLocalFilePopup->setItemEnabled(id,i->transfer()->terminated()); - m_pContextPopup->insertItem(__tr2qs_ctx("Local &File","filetransferwindow"),m_pLocalFilePopup); - - - } - - i->transfer()->fillContextPopup(m_pContextPopup); - m_pContextPopup->insertSeparator(); - } - } - - - bool bHaveTerminated = false; - int i; - KviFileTransferItem * item; - - for(i=0;irowCount();i++) - { - item = (KviFileTransferItem *)m_pTableWidget->item(i,0); - if(!item) - continue; - - if(item->transfer()->terminated()) - { - bHaveTerminated = true; - break; - } - } - - id = m_pContextPopup->insertItem(__tr2qs_ctx("&Clear Terminated","filetransferwindow"),this,SLOT(clearTerminated())); - m_pContextPopup->setItemEnabled(id,bHaveTerminated); - - bool bAreTransfersActive = false; - if(m_pTableWidget->rowCount() >= 1) - bAreTransfersActive = true; - - id = m_pContextPopup->insertItem(__tr2qs_ctx("Clear &All","filetransferwindow"),this,SLOT(clearAll())); - m_pContextPopup->setItemEnabled(id,bAreTransfersActive); - - m_pContextPopup->popup(pnt); -} - - -KviFileTransfer * KviFileTransferWindow::selectedTransfer() -{ - if(m_pTableWidget->selectedItems().count() == 0) return 0; - KviFileTransferItem * it = (KviFileTransferItem *)m_pTableWidget->selectedItems().first(); - if(!it)return 0; - KviFileTransferItem * i = (KviFileTransferItem *)it; - return i->transfer(); -} - -void KviFileTransferWindow::openFilePopupActivated(int id) -{ -#ifdef COMPILE_KDE_SUPPORT - int ip = m_pOpenFilePopup->itemParameter(id); - if(ip < 0)return; - - KviFileTransfer * t = selectedTransfer(); - if(!t)return; - QString tmp = t->localFileName(); - if(tmp.isEmpty())return; - - - QString mimetype = KMimeType::findByPath(tmp)->name(); - KService::List offers = KMimeTypeTrader::self()->query(mimetype,"Application"); - - int idx = 0; - for(KService::List::Iterator itOffers = offers.begin(); - itOffers != offers.end(); ++itOffers) - { - if(idx == ip) - { - KUrl::List lst; - KUrl url; - url.setPath(tmp); - lst.append(url); - KRun::run(*((*itOffers).data()),lst,g_pFrame); - break; - } - idx++; - } -#endif //COMPILE_KDE_SUPPORT -} - -void KviFileTransferWindow::openLocalFileTerminal() -{ -//-| Grifisx & Noldor |- -#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - KviFileTransfer * t = selectedTransfer(); - if(!t)return; - QString tmp = t->localFileName(); - if(tmp.isEmpty())return; - int idx = tmp.lastIndexOf("/"); - if(idx == -1)return; - tmp = tmp.left(idx); - tmp.append("\""); - // FIXME: this is not a solution ...because if the drive isn't system's drive the command 'cd' naturaly doesn't work - tmp.prepend("cmd.exe /k cd \""); - system(tmp.toLocal8Bit().data()); -#else -// G&N end - #ifdef COMPILE_KDE_SUPPORT - KviFileTransfer * t = selectedTransfer(); - if(!t)return; - QString tmp = t->localFileName(); - if(tmp.isEmpty())return; - - int idx = tmp.lastIndexOf("/"); - if(idx == -1)return; - tmp = tmp.left(idx); - - tmp.prepend("konsole --workdir=\""); - tmp.append("\""); - - KRun::runCommand(tmp,g_pFrame); - #endif //COMPILE_KDE_SUPPORT -#endif -} - -void KviFileTransferWindow::deleteLocalFile() -{ - KviFileTransfer * t = selectedTransfer(); - if(!t)return; - - QString fName = t->localFileName(); - QString tmp; - - KviQString::sprintf(tmp,__tr2qs_ctx("Do you really want to delete the file %Q?","filetransferwindow"),&fName); - - if(QMessageBox::warning(this,__tr2qs_ctx("Confirm delete","filetransferwindow"), - tmp,__tr2qs_ctx("Yes","filetransferwindow"),__tr2qs_ctx("No","filetransferwindow")) != 0) - return; - - if(!QFile::remove(fName)) - QMessageBox::warning(this,__tr2qs_ctx("Delete failed","filetransferwindow"), - __tr2qs_ctx("Failed to remove the file","filetransferwindow"), - __tr2qs_ctx("OK","filetransferwindow")); -} - -void KviFileTransferWindow::openLocalFile() -{ -//-| Grifisx & Noldor |- -#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - - KviFileTransfer * t = selectedTransfer(); - if(!t)return; - QString tmp = t->localFileName(); - if(tmp.isEmpty())return; - tmp.replace("/","\\"); - ShellExecute(0,"open",tmp.toLocal8Bit().data(),NULL,NULL,SW_SHOWNORMAL); //You have to link the shell32.lib -#else -// G&N end - #ifdef COMPILE_KDE_SUPPORT - KviFileTransfer * t = selectedTransfer(); - if(!t)return; - QString tmp = t->localFileName(); - if(tmp.isEmpty())return; - - QString mimetype = KMimeType::findByPath(tmp)->name(); //KMimeType - KService::Ptr offer = KMimeTypeTrader::self()->preferredService(mimetype,"Application"); - if(!offer) - { - openLocalFileWith(); - return; - } - - KUrl::List lst; - KUrl url; - url.setPath(tmp); - lst.append(url); - - KRun::run(*offer, lst, g_pFrame); - #endif //COMPILE_KDE_SUPPORT -#endif -} - -void KviFileTransferWindow::openLocalFileWith() -{ -//-| Grifisx & Noldor |- -#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - KviFileTransfer * t = selectedTransfer(); - if(!t)return; - QString tmp = t->localFileName(); - if(tmp.isEmpty())return; - tmp.replace("/","\\"); - tmp.prepend("rundll32.exe shell32.dll,OpenAs_RunDLL "); // this if to show the 'open with...' window - WinExec(tmp.toLocal8Bit().data(),SW_SHOWNORMAL); -#else -// G&N end - #ifdef COMPILE_KDE_SUPPORT - KviFileTransfer * t = selectedTransfer(); - if(!t)return; - QString tmp = t->localFileName(); - if(tmp.isEmpty())return; - - KUrl::List lst; - KUrl url; - url.setPath(tmp); - lst.append(url); - KRun::displayOpenWithDialog(lst,g_pFrame); - #endif //COMPILE_KDE_SUPPORT -#endif -} - -void KviFileTransferWindow::copyLocalFileToClipboard() -{ - KviFileTransfer * t = selectedTransfer(); - if(!t)return; - QString tmp = t->localFileName(); - if(tmp.isEmpty())return; - QApplication::clipboard()->setText(tmp); -} - -void KviFileTransferWindow::openLocalFileFolder() -{ -//-| Grifisx & Noldor|- -#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - KviFileTransfer * t = selectedTransfer(); - if(!t)return; - QString tmp = t->localFileName(); - if(tmp.isEmpty())return; - tmp=QFileInfo(tmp).absolutePath(); - tmp.replace('/','\\'); - tmp.prepend("explorer.exe "); - WinExec(tmp.toLocal8Bit().data(), SW_MAXIMIZE); -#else -// G&N end - #ifdef COMPILE_KDE_SUPPORT - KviFileTransfer * t = selectedTransfer(); - if(!t)return; - QString tmp = t->localFileName(); - if(tmp.isEmpty())return; - - int idx = tmp.lastIndexOf("/"); - if(idx == -1)return; - tmp = tmp.left(idx); - - QString mimetype = KMimeType::findByPath(tmp)->name(); // inode/directory - KService::Ptr offer = KMimeTypeTrader::self()->preferredService(mimetype,"Application"); - if(!offer)return; - - KUrl::List lst; - KUrl url; - url.setPath(tmp); - lst.append(url); - KRun::run(*offer,lst,g_pFrame); - #endif //COMPILE_KDE_SUPPORT -#endif -} - -void KviFileTransferWindow::heartbeat() -{ - int i; - QModelIndex index; - KviFileTransferItem* it; - int dummy = (int) time(NULL); - - for(i=0;i<=m_pTableWidget->rowCount();i++) - { - it = (KviFileTransferItem *)m_pTableWidget->item(i,0); - - if(!it) - continue; - - if(it->transfer()->active()) - { - m_pTableWidget->model()->setData(m_pTableWidget->model()->index(i,0), dummy, Qt::DisplayRole); - m_pTableWidget->model()->setData(m_pTableWidget->model()->index(i,1), dummy, Qt::DisplayRole); - m_pTableWidget->model()->setData(m_pTableWidget->model()->index(i,2), dummy, Qt::DisplayRole); - } - } -} - -void KviFileTransferWindow::clearAll() -{ - QString tmp; - - bool bHaveAllTerminated = true; - int i; - KviFileTransferItem * item; - - for(i=0;irowCount();i++) - { - item = (KviFileTransferItem *)m_pTableWidget->item(i,0); - if(!item) - continue; - - if(!item->transfer()->terminated()) - { - bHaveAllTerminated = false; - break; - } - } - - KviQString::sprintf(tmp,__tr2qs_ctx("Clear all transfers, including any in progress?","filetransferwindow")); - - // If any transfer is active asks for confirm - if(!bHaveAllTerminated) - if(QMessageBox::warning(this,__tr2qs_ctx("Clear All Transfers? - KVIrc","filetransferwindow"), tmp,__tr2qs_ctx("Yes","filetransferwindow"),__tr2qs_ctx("No","filetransferwindow")) != 0) - return; - - KviFileTransferManager::instance()->killAllTransfers(); -} - -void KviFileTransferWindow::clearTerminated() -{ - KviFileTransferManager::instance()->killTerminatedTransfers(); -} - -void KviFileTransferWindow::getBaseLogFileName(QString &buffer) -{ - buffer.sprintf("FILETRANSFER"); -} - -QPixmap * KviFileTransferWindow::myIconPtr() -{ - return g_pIconManager->getSmallIcon(KVI_SMALLICON_FILETRANSFER); -} - -void KviFileTransferWindow::resizeEvent(QResizeEvent *) -{ - m_pSplitter->setGeometry(0,0,width(),height()); -} - -QSize KviFileTransferWindow::sizeHint() const -{ - return m_pSplitter->sizeHint(); -} - -void KviFileTransferWindow::fillCaptionBuffers() -{ - m_szPlainTextCaption = __tr2qs_ctx("File Transfers","filetransferwindow"); -} - -void KviFileTransferWindow::die() -{ - close(); -} - - - -//#warning "Load & save properties of this kind of window" - -//void KviFileTransferWindow::saveProperties() -//{ -// KviWindowProperty p; -// p.rect = externalGeometry(); -// p.isDocked = isAttacched(); -// QValueList l(m_pSplitter->sizes()); -// if(l.count() >= 1)p.splitWidth1 = *(l.at(0)); -// if(l.count() >= 2)p.splitWidth2 = *(l.at(1)); -// p.timestamp = m_pView->timestamp(); -// p.imagesVisible = m_pView->imagesVisible(); -// p.isMaximized = isAttacched() && isMaximized(); -// p.topSplitWidth1 = 0; -// p.topSplitWidth2 = 0; -// p.topSplitWidth3 = 0; -// g_pOptions->m_pWinPropertiesList->setProperty(caption(),&p); -//} -// -//void KviFileTransferWindow::setProperties(KviWindowProperty *p) -//{ -// QValueList l; -// l.append(p->splitWidth1); -// l.append(p->splitWidth2); -// m_pVertSplitter->setSizes(l); -// m_pIrcView->setTimestamp(p->timestamp); -// m_pIrcView->setShowImages(p->imagesVisible); -//} - -void KviFileTransferWindow::applyOptions() -{ - m_pIrcView->applyOptions(); - KviWindow::applyOptions(); -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_filetransferwindow.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/filetransferwindow/filetransferwindow.h b/src/modules/filetransferwindow/filetransferwindow.h deleted file mode 100644 index a32a6c220..000000000 --- a/src/modules/filetransferwindow/filetransferwindow.h +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef _FILETRANSFERWINDOW_H_ -#define _FILETRANSFERWINDOW_H_ -//============================================================================= -// -// File : filetransferwindow.h -// Creation date : Mon Apr 21 2003 23:14:12 CEST by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2003-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the linkss of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "KviWindow.h" -#include "KviCString.h" -#include "KviIrcSocket.h" -#include "KviIrcServerParser.h" -#include "KviConsoleWindow.h" -#include "KviModuleExtension.h" -#include "KviFileTransfer.h" -#include "KviDynamicToolTip.h" -#include "KviTalTableWidget.h" -#include "KviTalPopupMenu.h" -#include "KviTalIconAndRichTextItemDelegate.h" - -#include -#include - -class KviFileTransferItem; - -class KviFileTransferWidget : public KviTalTableWidget -{ - friend class KviFileTransferItemDelegate; - Q_OBJECT - Q_PROPERTY(int TransparencyCapable READ dummyRead) -public: - KviFileTransferWidget(QWidget * pParent); - ~KviFileTransferWidget() {}; - void paintEvent(QPaintEvent * event); - int dummyRead() const { return 0; }; -protected: - void mousePressEvent (QMouseEvent *e); - void mouseDoubleClickEvent (QMouseEvent *e); -signals: - void rightButtonPressed(KviFileTransferItem *,QPoint pnt); - void doubleClicked(KviFileTransferItem *,QPoint pnt); -}; - -class KviFileTransferItem : public KviTalTableWidgetItemEx -{ -public: - KviFileTransferItem(KviFileTransferWidget * v,KviFileTransfer * t); - ~KviFileTransferItem(); -protected: - KviFileTransfer * m_pTransfer; - KviTalTableWidgetItem * col1Item; //item on the second column - KviTalTableWidgetItem * col2Item; //item on the third column -public: - KviFileTransfer * transfer(){ return m_pTransfer; }; - virtual QString key(int column,bool bAcending) const; - virtual void displayUpdate(); -}; - -class KviFileTransferItemDelegate : public KviTalIconAndRichTextItemDelegate -{ - Q_OBJECT -public: - KviFileTransferItemDelegate(QAbstractItemView * pWidget=0) - : KviTalIconAndRichTextItemDelegate(pWidget) {}; - ~KviFileTransferItemDelegate(){}; - QSize sizeHint(const QStyleOptionViewItem &option,const QModelIndex &index) const; - void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const; -}; - -class KviFileTransferWindow : public KviWindow, public KviModuleExtension -{ - friend class KviFileTransferItem; - friend class KviFileTransferItemDelegate; - Q_OBJECT -public: - KviFileTransferWindow(KviModuleExtensionDescriptor * d,KviMainWindow * lpFrm); - ~KviFileTransferWindow(); -protected: - QSplitter * m_pVertSplitter; - KviFileTransferWidget * m_pTableWidget; - QAbstractItemDelegate * m_pItemDelegate; - KviTalPopupMenu * m_pContextPopup; - KviTalPopupMenu * m_pLocalFilePopup; - KviTalPopupMenu * m_pOpenFilePopup; - QTimer * m_pTimer; - int m_iLineSpacing; // cached fm value -public: // Methods - virtual void die(); -protected: - virtual QPixmap * myIconPtr(); - virtual void fillCaptionBuffers(); - virtual void applyOptions(); - virtual void resizeEvent(QResizeEvent *e); - virtual void getBaseLogFileName(QString &buffer); - KviFileTransferItem * findItem(KviFileTransfer * t); - void fillTransferView(); - KviFileTransfer * selectedTransfer(); - virtual void fontChange(const QFont &oldFont); - bool eventFilter( QObject *obj, QEvent *ev ); -public: - virtual QSize sizeHint() const; - int lineSpacing(){ return m_iLineSpacing; }; -protected slots: - void transferRegistered(KviFileTransfer *t); - void transferUnregistering(KviFileTransfer *t); - void rightButtonPressed(KviFileTransferItem *it,const QPoint &pnt); - void doubleClicked(KviFileTransferItem *it,const QPoint &pnt); - void heartbeat(); - void clearTerminated(); - void clearAll(); - void tipRequest(KviDynamicToolTip * tip,const QPoint &pnt); - void openLocalFile(); - void openLocalFileWith(); - void copyLocalFileToClipboard(); - void openLocalFileFolder(); - void openFilePopupActivated(int id); - void openLocalFileTerminal(); - void deleteLocalFile(); -}; - -#endif //_FILETRANSFERWINDOW_H_ diff --git a/src/modules/filetransferwindow/libkvifiletransferwindow.cpp b/src/modules/filetransferwindow/libkvifiletransferwindow.cpp index 35040e431..a6cddb5f8 100644 --- a/src/modules/filetransferwindow/libkvifiletransferwindow.cpp +++ b/src/modules/filetransferwindow/libkvifiletransferwindow.cpp @@ -21,7 +21,7 @@ // //============================================================================= -#include "filetransferwindow.h" +#include "FileTransferWindow.h" #include "KviModule.h" #include "KviApplication.h" @@ -32,7 +32,7 @@ #include -KviFileTransferWindow * g_pFileTransferWindow = 0; +FileTransferWindow * g_pFileTransferWindow = 0; static KviModuleExtension * filetransferwindow_extension_alloc(KviModuleExtensionAllocStruct * s) { @@ -55,7 +55,7 @@ static KviModuleExtension * filetransferwindow_extension_alloc(KviModuleExtensio } } - g_pFileTransferWindow = new KviFileTransferWindow(s->pDescriptor,g_pFrame); + g_pFileTransferWindow = new FileTransferWindow(s->pDescriptor,g_pFrame); g_pFrame->addWindow(g_pFileTransferWindow,!bCreateMinimized); if(bCreateMinimized)g_pFileTransferWindow->minimize(); return g_pFileTransferWindow; diff --git a/src/modules/help/CMakeLists.txt b/src/modules/help/CMakeLists.txt index ac9d04d02..567f94e88 100644 --- a/src/modules/help/CMakeLists.txt +++ b/src/modules/help/CMakeLists.txt @@ -1,16 +1,16 @@ # CMakeLists for src/modules/help SET(kvihelp_MOC_HDRS - helpwidget.h - helpwindow.h - index.h + HelpWidget.h + HelpWindow.h + HelpIndex.h ) SET(kvihelp_SRCS libkvihelp.cpp - helpwidget.cpp - helpwindow.cpp - index.cpp + HelpWidget.cpp + HelpWindow.cpp + HelpIndex.cpp ) # After this call, files will be moc'ed to moc_kvi_*.cpp diff --git a/src/modules/help/HelpIndex.cpp b/src/modules/help/HelpIndex.cpp new file mode 100644 index 000000000..5d9ddc062 --- /dev/null +++ b/src/modules/help/HelpIndex.cpp @@ -0,0 +1,602 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt Assistant of the Qt Toolkit. +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information +** to ensure GNU General Public Licensing requirements will be met: +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. In addition, as a special +** exception, Nokia gives you certain additional rights. These rights +** are described in the Nokia Qt GPL Exception version 1.3, included in +** the file GPL_EXCEPTION.txt in this package. +** +** Qt for Windows(R) Licensees +** As a special exception, Nokia, as the sole copyright holder for Qt +** Designer, grants users of the Qt/Eclipse Integration plug-in the +** right for the Qt/Eclipse Integration to link to functionality +** provided by Qt Designer and its related libraries. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +#include "HelpIndex.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +struct Term { + Term() : frequency(-1) {} + Term( const QString &t, int f, QVector l ) : term( t ), frequency( f ), documents( l ) {} + QString term; + int frequency; + QVectordocuments; + bool operator<( const Term &i2 ) const { return frequency < i2.frequency; } +}; + +QDataStream &operator>>( QDataStream &s, Document &l ) +{ + s >> l.docNumber; + s >> l.frequency; + return s; +} + +QDataStream &operator<<( QDataStream &s, const Document &l ) +{ + s << (qint16)l.docNumber; + s << (qint16)l.frequency; + return s; +} + +HelpIndex::HelpIndex( const QString &dp, const QString &hp ) + : QObject( 0 ), docPath( dp ) +{ + Q_UNUSED(hp); + + alreadyHaveDocList = false; + lastWindowClosed = false; + connect( qApp, SIGNAL(lastWindowClosed()), + this, SLOT(setLastWinClosed()) ); + + m_pTimer = new QTimer(this); + m_pTimer->setSingleShot(true); + m_pTimer->setInterval(0); + connect(m_pTimer, SIGNAL(timeout()), this, SLOT(filterNext())); +} + +HelpIndex::HelpIndex( const QStringList &dl, const QString &hp ) + : QObject( 0 ) +{ + Q_UNUSED(hp); + docList = dl; + alreadyHaveDocList = true; + lastWindowClosed = false; + connect( qApp, SIGNAL(lastWindowClosed()), + this, SLOT(setLastWinClosed()) ); +} + +void HelpIndex::setLastWinClosed() +{ + lastWindowClosed = true; +} + +void HelpIndex::setDictionaryFile( const QString &f ) +{ + dictFile = f; +} + +void HelpIndex::setDocListFile( const QString &f ) +{ + docListFile = f; +} + +void HelpIndex::setDocList( const QStringList &lst ) +{ + docList = lst; +} + +void HelpIndex::makeIndex() +{ + if ( !alreadyHaveDocList ) + setupDocumentList(); + + lastWindowClosed = false; + emit indexingStart( docList.count() ); + dict.clear(); + m_iCurItem = 0; + m_pTimer->start(); //singleshot +} + +void HelpIndex::filterNext() +{ + if(m_iCurItem < docList.count() && !lastWindowClosed) + { + QUrl url(docList.at(m_iCurItem)); + parseDocument( url.toLocalFile(), m_iCurItem ); + emit indexingProgress( m_iCurItem ); + m_iCurItem++; + m_pTimer->start(); //singleshot + } else { + emit indexingEnd(); + } +} + +void HelpIndex::setupDocumentList() +{ + docList.clear(); + titleList.clear(); + QDir d( docPath ); + QStringList filters; + filters.append(QLatin1String("*.html")); + QStringList lst = d.entryList(filters); + QStringList::ConstIterator it = lst.constBegin(); + for ( ; it != lst.constEnd(); ++it ) + { + QString filename=QLatin1String("file:") + docPath + QLatin1String("/") + *it ; + docList.append(filename); + titleList.append(getDocumentTitle(filename)); + } +} + +void HelpIndex::insertInDict( const QString &str, int docNum ) +{ + if ( str == QLatin1String("amp") || str == QLatin1String("nbsp")) + return; + Entry *e = 0; + if ( dict.count() ) + e = dict[ str ]; + + if ( e ) { + if ( e->documents.last().docNumber != docNum ) + e->documents.append( Document(docNum, 1 ) ); + else + e->documents.last().frequency++; + } else { + dict.insert( str, new Entry( docNum ) ); + } +} + +QString HelpIndex::getCharsetForDocument(QFile *file) +{ + QTextStream s(file); + QString contents = s.readAll(); + + QString encoding; + int start = contents.indexOf(QLatin1String(" 0) { + int end = contents.indexOf(QLatin1String(">"), start); + QString meta = contents.mid(start+5, end-start); + meta = meta.toLower(); + QRegExp r(QLatin1String("charset=([^\"\\s]+)")); + if (r.indexIn(meta) != -1) { + encoding = r.cap(1); + } + } + + file->seek(0); + if (encoding.isEmpty()) + return QLatin1String("utf-8"); + return encoding; +} + +void HelpIndex::parseDocument( const QString &filename, int docNum ) +{ + QFile file( filename ); + if ( !file.open(QFile::ReadOnly) ) { + qWarning( "can not open file %s", qPrintable(filename) ); + return; + } + + QTextStream s(&file); + QString en = getCharsetForDocument(&file); + s.setCodec(QTextCodec::codecForName(en.toLatin1().constData())); + + QString text = s.readAll(); + if (text.isNull()) + return; + + bool valid = true; + const QChar *buf = text.unicode(); + QChar str[64]; + QChar c = buf[0]; + int j = 0; + int i = 0; + while ( j < text.length() ) { + if ( c == QLatin1Char('<') || c == QLatin1Char('&') ) { + valid = false; + if ( i > 1 ) + insertInDict( QString(str,i), docNum ); + i = 0; + c = buf[++j]; + continue; + } + if ( ( c == QLatin1Char('>') || c == QLatin1Char(';') ) && !valid ) { + valid = true; + c = buf[++j]; + continue; + } + if ( !valid ) { + c = buf[++j]; + continue; + } + if ( ( c.isLetterOrNumber() || c == QLatin1Char('_') ) && i < 63 ) { + str[i] = c.toLower(); + ++i; + } else { + if ( i > 1 ) + insertInDict( QString(str,i), docNum ); + i = 0; + } + c = buf[++j]; + } + if ( i > 1 ) + insertInDict( QString(str,i), docNum ); + file.close(); +} + +void HelpIndex::writeDict() +{ + QFile f( dictFile ); + if ( !f.open(QFile::WriteOnly ) ) + return; + QDataStream s( &f ); + for(QHash::Iterator it = dict.begin(); it != dict.end(); ++it) { + s << it.key(); + s << it.value()->documents.count(); + s << it.value()->documents; + } + f.close(); + writeDocumentList(); +} + +void HelpIndex::writeDocumentList() +{ + QFile f( docListFile ); + if ( !f.open(QFile::WriteOnly ) ) + return; + QDataStream s( &f ); + s << docList; + + QFile f1( docListFile+".titles" ); + if ( !f1.open(QFile::WriteOnly ) ) + return; + QDataStream s1( &f1 ); + s1 << titleList; + +} + +void HelpIndex::readDict() +{ + QFile f( dictFile ); + if ( !f.open(QFile::ReadOnly ) ) + return; + + dict.clear(); + QDataStream s( &f ); + QString key; + int numOfDocs; + QVector docs; + while ( !s.atEnd() ) { + s >> key; + s >> numOfDocs; + docs.resize(numOfDocs); + s >> docs; + dict.insert( key, new Entry( docs ) ); + } + f.close(); + readDocumentList(); +} + +void HelpIndex::readDocumentList() +{ + QFile f( docListFile ); + if ( !f.open(QFile::ReadOnly ) ) + return; + QDataStream s( &f ); + s >> docList; + QFile f1( docListFile+".titles" ); + if ( !f1.open(QFile::ReadOnly ) ) + return; + QDataStream s1( &f1 ); + s1 >> titleList; +} + +QStringList HelpIndex::query( const QStringList &terms, const QStringList &termSeq, const QStringList &seqWords ) +{ + QList termList; + for (QStringList::ConstIterator it = terms.begin(); it != terms.end(); ++it ) { + Entry *e = 0; + if ( (*it).contains(QLatin1Char('*')) ) { + QVector wcts = setupDummyTerm( getWildcardTerms( *it ) ); + termList.append( Term(QLatin1String("dummy"), wcts.count(), wcts ) ); + } else if ( dict[ *it ] ) { + e = dict[ *it ]; + termList.append( Term( *it, e->documents.count(), e->documents ) ); + } else { + return QStringList(); + } + } + if ( !termList.count() ) + return QStringList(); + qSort(termList); + + QVector minDocs = termList.takeFirst().documents; + for(QList::Iterator it = termList.begin(); it != termList.end(); ++it) { + Term *t = &(*it); + QVector docs = t->documents; + for(QVector::Iterator minDoc_it = minDocs.begin(); minDoc_it != minDocs.end(); ) { + bool found = false; + for (QVector::ConstIterator doc_it = docs.constBegin(); doc_it != docs.constEnd(); ++doc_it ) { + if ( (*minDoc_it).docNumber == (*doc_it).docNumber ) { + (*minDoc_it).frequency += (*doc_it).frequency; + found = true; + break; + } + } + if ( !found ) + minDoc_it = minDocs.erase( minDoc_it ); + else + ++minDoc_it; + } + } + + QStringList results; + qSort( minDocs ); + if ( termSeq.isEmpty() ) { + for(QVector::Iterator it = minDocs.begin(); it != minDocs.end(); ++it) + results << docList.at((int)(*it).docNumber); + return results; + } + + QString fileName; + for(QVector::Iterator it = minDocs.begin(); it != minDocs.end(); ++it) { + fileName = docList[ (int)(*it).docNumber ]; + if ( searchForPattern( termSeq, seqWords, fileName ) ) + results << fileName; + } + return results; +} + +QString HelpIndex::getDocumentTitle( const QString &fullFileName ) +{ + QUrl url(fullFileName); + QString fileName = url.toLocalFile(); + + if (documentTitleCache.contains(fileName)) + return documentTitleCache.value(fileName); + + QFile file( fileName ); + if ( !file.open( QFile::ReadOnly ) ) { + qWarning( "cannot open file %s", qPrintable(fileName) ); + return fileName; + } + QTextStream s( &file ); + QString text = s.readAll(); + + int start = text.indexOf(QLatin1String(""), 0, Qt::CaseInsensitive) + 7; + int end = text.indexOf(QLatin1String(""), 0, Qt::CaseInsensitive); + + QString title = tr("Untitled"); + if (end - start > 0) { + title = text.mid(start, end - start); + if (Qt::mightBeRichText(title)) { + QTextDocument doc; + doc.setHtml(title); + title = doc.toPlainText(); + } + } + documentTitleCache.insert(fileName, title); + return title; +} + +QStringList HelpIndex::getWildcardTerms( const QString &term ) +{ + QStringList lst; + QStringList terms = split( term ); + QStringList::Iterator iter; + + for(QHash::Iterator it = dict.begin(); it != dict.end(); ++it) { + int index = 0; + bool found = false; + QString text( it.key() ); + for ( iter = terms.begin(); iter != terms.end(); ++iter ) { + if ( *iter == QLatin1String("*") ) { + found = true; + continue; + } + if ( iter == terms.begin() && (*iter)[0] != text[0] ) { + found = false; + break; + } + index = text.indexOf( *iter, index ); + if ( *iter == terms.last() && index != (int)text.length()-1 ) { + index = text.lastIndexOf( *iter ); + if ( index != (int)text.length() - (int)(*iter).length() ) { + found = false; + break; + } + } + if ( index != -1 ) { + found = true; + index += (*iter).length(); + continue; + } else { + found = false; + break; + } + } + if ( found ) + lst << text; + } + + return lst; +} + +QStringList HelpIndex::split( const QString &str ) +{ + QStringList lst; + int j = 0; + int i = str.indexOf(QLatin1Char('*'), j ); + + if (str.startsWith(QLatin1String("*"))) + lst << QLatin1String("*"); + + while ( i != -1 ) { + if ( i > j && i <= (int)str.length() ) { + lst << str.mid( j, i - j ); + lst << QLatin1String("*"); + } + j = i + 1; + i = str.indexOf(QLatin1Char('*'), j ); + } + + int l = str.length() - 1; + if ( str.mid( j, l - j + 1 ).length() > 0 ) + lst << str.mid( j, l - j + 1 ); + + return lst; +} + +QVector HelpIndex::setupDummyTerm( const QStringList &terms ) +{ + QList termList; + for (QStringList::ConstIterator it = terms.begin(); it != terms.end(); ++it) { + Entry *e = 0; + if ( dict[ *it ] ) { + e = dict[ *it ]; + termList.append( Term( *it, e->documents.count(), e->documents ) ); + } + } + QVector maxList(0); + if ( !termList.count() ) + return maxList; + qSort(termList); + + maxList = termList.takeLast().documents; + for(QList::Iterator it = termList.begin(); it != termList.end(); ++it) { + Term *t = &(*it); + QVector docs = t->documents; + for (QVector::iterator docIt = docs.begin(); docIt != docs.end(); ++docIt ) { + if ( maxList.indexOf( *docIt ) == -1 ) + maxList.append( *docIt ); + } + } + return maxList; +} + +void HelpIndex::buildMiniDict( const QString &str ) +{ + if ( miniDict[ str ] ) + miniDict[ str ]->positions.append( wordNum ); + ++wordNum; +} + +bool HelpIndex::searchForPattern( const QStringList &patterns, const QStringList &words, const QString &fileName ) +{ + QUrl url(fileName); + QString fName = url.toLocalFile(); + QFile file( fName ); + if ( !file.open( QFile::ReadOnly ) ) { + qWarning( "cannot open file %s", qPrintable(fName) ); + return false; + } + + wordNum = 3; + miniDict.clear(); + QStringList::ConstIterator cIt = words.begin(); + for ( ; cIt != words.end(); ++cIt ) + miniDict.insert( *cIt, new PosEntry( 0 ) ); + + QTextStream s( &file ); + QString text = s.readAll(); + bool valid = true; + const QChar *buf = text.unicode(); + QChar str[64]; + QChar c = buf[0]; + int j = 0; + int i = 0; + while ( j < text.length() ) { + if ( c == QLatin1Char('<') || c == QLatin1Char('&') ) { + valid = false; + if ( i > 1 ) + buildMiniDict( QString(str,i) ); + i = 0; + c = buf[++j]; + continue; + } + if ( ( c == QLatin1Char('>') || c == QLatin1Char(';') ) && !valid ) { + valid = true; + c = buf[++j]; + continue; + } + if ( !valid ) { + c = buf[++j]; + continue; + } + if ( ( c.isLetterOrNumber() || c == QLatin1Char('_') ) && i < 63 ) { + str[i] = c.toLower(); + ++i; + } else { + if ( i > 1 ) + buildMiniDict( QString(str,i) ); + i = 0; + } + c = buf[++j]; + } + if ( i > 1 ) + buildMiniDict( QString(str,i) ); + file.close(); + + QStringList::ConstIterator patIt = patterns.begin(); + QStringList wordLst; + QList a, b; + QList::iterator aIt; + for ( ; patIt != patterns.end(); ++patIt ) { + wordLst = (*patIt).split(QLatin1Char(' ')); + a = miniDict[ wordLst[0] ]->positions; + for ( int j = 1; j < (int)wordLst.count(); ++j ) { + b = miniDict[ wordLst[j] ]->positions; + aIt = a.begin(); + while ( aIt != a.end() ) { + if ( b.contains( *aIt + 1 )) { + (*aIt)++; + ++aIt; + } else { + aIt = a.erase( aIt ); + } + } + } + } + if ( a.count() ) + return true; + return false; +} + +QT_END_NAMESPACE diff --git a/src/modules/help/HelpIndex.h b/src/modules/help/HelpIndex.h new file mode 100644 index 000000000..6eb1cdf6c --- /dev/null +++ b/src/modules/help/HelpIndex.h @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt Assistant of the Qt Toolkit. +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information +** to ensure GNU General Public Licensing requirements will be met: +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. In addition, as a special +** exception, Nokia gives you certain additional rights. These rights +** are described in the Nokia Qt GPL Exception version 1.3, included in +** the file GPL_EXCEPTION.txt in this package. +** +** Qt for Windows(R) Licensees +** As a special exception, Nokia, as the sole copyright holder for Qt +** Designer, grants users of the Qt/Eclipse Integration plug-in the +** right for the Qt/Eclipse Integration to link to functionality +** provided by Qt Designer and its related libraries. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +#ifndef INDEX_H +#define INDEX_H + +#include +#include +#include +#include +#include +#include +#include + +class QTimer; + +QT_BEGIN_NAMESPACE + +struct Document { + Document( int d, int f ) : docNumber( d ), frequency( f ) {} + Document() : docNumber( -1 ), frequency( 0 ) {} + bool operator==( const Document &doc ) const { + return docNumber == doc.docNumber; + } + bool operator<( const Document &doc ) const { + return frequency > doc.frequency; + } + bool operator<=( const Document &doc ) const { + return frequency >= doc.frequency; + } + bool operator>( const Document &doc ) const { + return frequency < doc.frequency; + } + qint16 docNumber; + qint16 frequency; +}; + +QDataStream &operator>>( QDataStream &s, Document &l ); +QDataStream &operator<<( QDataStream &s, const Document &l ); + +class HelpIndex : public QObject +{ + Q_OBJECT +public: + struct Entry { + Entry( int d ) { documents.append( Document( d, 1 ) ); } + Entry( QVector l ) : documents( l ) {} + QVector documents; + }; + struct PosEntry { + PosEntry( int p ) { positions.append( p ); } + QList positions; + }; + + HelpIndex( const QString &dp, const QString &hp ); + HelpIndex( const QStringList &dl, const QString &hp ); + void writeDict(); + void readDict(); + void makeIndex(); + QStringList query( const QStringList&, const QStringList&, const QStringList& ); + QString getDocumentTitle( const QString& ); + void setDictionaryFile( const QString& ); + void setDocListFile( const QString& ); + void setDocList( const QStringList & ); + + const QStringList& documentList() { return docList; }; + const QStringList& titlesList() { return titleList; }; + +signals: + void indexingStart( int ); + void indexingProgress( int ); + void indexingEnd(); + +private slots: + void setLastWinClosed(); + void filterNext(); +private: + void setupDocumentList(); + void parseDocument( const QString&, int ); + void insertInDict( const QString&, int ); + void writeDocumentList(); + void readDocumentList(); + QStringList getWildcardTerms( const QString& ); + QStringList split( const QString& ); + QVector setupDummyTerm( const QStringList& ); + bool searchForPattern( const QStringList&, const QStringList&, const QString& ); + void buildMiniDict( const QString& ); + QString getCharsetForDocument(QFile *); + QStringList docList; + QStringList titleList; + QHash dict; + QHash miniDict; + uint wordNum; + QString docPath; + QString dictFile, docListFile; + bool alreadyHaveDocList; + bool lastWindowClosed; + QHash documentTitleCache; + QTimer * m_pTimer; + int m_iCurItem; +}; + +#endif + +QT_END_NAMESPACE diff --git a/src/modules/help/HelpWidget.cpp b/src/modules/help/HelpWidget.cpp new file mode 100644 index 000000000..e7f5d53f3 --- /dev/null +++ b/src/modules/help/HelpWidget.cpp @@ -0,0 +1,137 @@ +//============================================================================= +// +// File : HelpWidget.cpp +// Creation date : Thu Aug 10 2000 17:42:12 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "HelpWidget.h" +#include "HelpWindow.h" + +#include "KviMainWindow.h" +#include "KviIconManager.h" +#include "KviLocale.h" +#include "KviApplication.h" +#include "KviMessageBox.h" +#include "KviModule.h" +#include "KviFileUtils.h" + +#include +#include +#include +#include +#include +#include + +extern HelpIndex * g_pDocIndex; +extern KviPointerList * g_pHelpWindowList; +extern KviPointerList * g_pHelpWidgetList; + +HelpWidget::HelpWidget(QWidget * par,KviMainWindow *,bool bIsStandalone) +: QWidget(par) +{ + setObjectName("help_widget"); + setMinimumWidth(80); + if(bIsStandalone)g_pHelpWidgetList->append(this); + m_bIsStandalone = bIsStandalone; + + m_pTextBrowser = new QTextBrowser(this); + m_pTextBrowser->setObjectName("text_browser"); + m_pTextBrowser->setFrameStyle(QFrame::StyledPanel|QFrame::Sunken); + m_pTextBrowser->setStyleSheet("QTextBrowser { background-color:white; color:black; }"); + m_pToolBar = new KviTalHBox(this); + + m_pBtnIndex = new QToolButton(m_pToolBar); + m_pBtnIndex->setIcon(*g_pIconManager->getBigIcon(KVI_BIGICON_HELPINDEX)); + connect(m_pBtnIndex,SIGNAL(clicked()),this,SLOT(showIndex())); + + m_pBtnBackward = new QToolButton(m_pToolBar); + m_pBtnBackward->setIcon(*g_pIconManager->getBigIcon(KVI_BIGICON_HELPBACK)); + connect(m_pBtnBackward,SIGNAL(clicked()),m_pTextBrowser,SLOT(backward())); + m_pBtnBackward->setEnabled(false); + + m_pBtnForward = new QToolButton(m_pToolBar); + m_pBtnForward->setIcon(*g_pIconManager->getBigIcon(KVI_BIGICON_HELPFORWARD)); + connect(m_pBtnForward,SIGNAL(clicked()),m_pTextBrowser,SLOT(forward())); + m_pBtnForward->setEnabled(false); + + QWidget* pSpacer=new QWidget(m_pToolBar); + + if(bIsStandalone) + { + QToolButton * b = new QToolButton(m_pToolBar); + b->setIcon(*g_pIconManager->getBigIcon(KVI_BIGICON_HELPCLOSE)); + connect(b,SIGNAL(clicked()),this,SLOT(doClose())); + } + + m_pToolBar->setStretchFactor(pSpacer,1); + connect(m_pTextBrowser,SIGNAL(backwardAvailable(bool)),m_pBtnBackward,SLOT(setEnabled(bool))); + connect(m_pTextBrowser,SIGNAL(forwardAvailable(bool)),m_pBtnForward,SLOT(setEnabled(bool))); +} + +HelpWidget::~HelpWidget() +{ + if(m_bIsStandalone)g_pHelpWidgetList->removeRef(this); +} + +void HelpWidget::showIndex() +{ + QString szHelpDir; + QDir dirHelp; + + g_pApp->getGlobalKvircDirectory(szHelpDir,KviApplication::Help); + dirHelp = QDir(szHelpDir); + + m_pTextBrowser->setSource(QUrl::fromLocalFile(dirHelp.absoluteFilePath("index.html"))); +} + +void HelpWidget::resizeEvent(QResizeEvent *) +{ + int hght = m_pToolBar->sizeHint().height(); + if(hght < 40)hght = 40; + m_pToolBar->setGeometry(0,0,width(),hght); + m_pTextBrowser->setGeometry(0,hght,width(),height() - hght); +} + +void HelpWidget::doClose() +{ + // hack needed to workaround "QToolBar::emulateButtonClicked()" + // that refers to the "this" pointer after this slot has been + // called (from the "too-small-toolbar-for-all-items-popup") + QTimer::singleShot(0,this,SLOT(suicide())); +} + +void HelpWidget::suicide() +{ + // goodbye cruel wolrd + delete this; +} + +QSize HelpWidget::sizeHint() const +{ + int wdth = m_pTextBrowser->sizeHint().width(); + if(m_pToolBar->sizeHint().width() > wdth)wdth = m_pToolBar->sizeHint().width(); + QSize s(wdth,m_pTextBrowser->sizeHint().height() + m_pToolBar->sizeHint().height()); + return s; +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "HelpWidget.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/help/HelpWidget.h b/src/modules/help/HelpWidget.h new file mode 100644 index 000000000..e94225f17 --- /dev/null +++ b/src/modules/help/HelpWidget.h @@ -0,0 +1,64 @@ +#ifndef _HELPWIDGET_H_ +#define _HELPWIDGET_H_ +//============================================================================= +// +// File : HelpWidget.h +// Creation date : Thu Aug 10 2000 17:26:20 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "HelpIndex.h" + +#include "KviTalHBox.h" + +#include +#include + +class QToolButton; +class QLineEdit; +class KviMainWindow; +//class QProcess; + +class HelpWidget : public QWidget +{ + Q_OBJECT +public: + HelpWidget(QWidget *par,KviMainWindow * lpFrm,bool bIsStandalone = false); + ~HelpWidget(); +private: + QToolButton * m_pBtnIndex; + QToolButton * m_pBtnBackward; + QToolButton * m_pBtnForward; + KviTalHBox * m_pToolBar; + QTextBrowser * m_pTextBrowser; + bool m_bIsStandalone; +protected: + virtual void resizeEvent(QResizeEvent *e); +protected slots: + void doClose(); + void showIndex(); + void suicide(); +public: + virtual QSize sizeHint() const; + QTextBrowser * textBrowser() { return m_pTextBrowser; } +}; + + +#endif //_HELPWIDGET_H_ diff --git a/src/modules/help/HelpWindow.cpp b/src/modules/help/HelpWindow.cpp new file mode 100644 index 000000000..5f58d85ed --- /dev/null +++ b/src/modules/help/HelpWindow.cpp @@ -0,0 +1,322 @@ +//============================================================================= +// +// File : HelpWindow.cpp +// Creation date : Tue Aug 11 2000 18:08:22 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the m_terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "HelpWindow.h" +#include "HelpWidget.h" + +#include "KviApplication.h" +#include "KviIconManager.h" +#include "KviOptions.h" +#include "KviLocale.h" +#include "KviModule.h" +#include "KviConfigurationFile.h" +#include "kvi_sourcesdate.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +extern HelpIndex * g_pDocIndex; +extern KviPointerList * g_pHelpWindowList; +extern KviPointerList * g_pHelpWidgetList; + +bool g_bIndexingDone = FALSE; +HelpWindow::HelpWindow(KviMainWindow * lpFrm,const char * name) +: KviWindow(KVI_WINDOW_TYPE_HELP,lpFrm,name) +{ + g_pHelpWindowList->append(this); + m_pSplitter = new KviTalSplitter(Qt::Horizontal,this); + m_pSplitter->setObjectName("main_splitter"); + m_pSplitter->setChildrenCollapsible(false); + + m_pHelpWidget = new HelpWidget(m_pSplitter,lpFrm); + + m_pToolBar=new KviTalVBox(m_pSplitter); + m_pTabWidget = new QTabWidget(m_pToolBar); + + m_pBottomLayout = new KviTalHBox(m_pToolBar); + m_pProgressBar = new QProgressBar(m_pBottomLayout); + m_pCancelButton = new QPushButton(m_pBottomLayout); + m_pCancelButton->setText(__tr2qs_ctx("Cancel","logview")); + connect(m_pCancelButton,SIGNAL(clicked()),g_pDocIndex,SLOT(setLastWinClosed())); + m_pBottomLayout->setVisible(false); + + m_pIndexTab = new KviTalVBox(m_pTabWidget); + m_pTabWidget->addTab(m_pIndexTab,__tr2qs("HelpIndex")); + + KviTalHBox* pSearchBox = new KviTalHBox(m_pIndexTab); + m_pIndexSearch = new QLineEdit(pSearchBox); + connect( m_pIndexSearch, SIGNAL( textChanged(const QString&) ), + this, SLOT( searchInIndex(const QString&) ) ); + connect( m_pIndexSearch, SIGNAL( returnPressed() ), + this, SLOT( showIndexTopic() ) ); + + m_pBtnRefreshIndex = new QPushButton(pSearchBox); + m_pBtnRefreshIndex->setIcon(*g_pIconManager->getBigIcon(KVI_REFRESH_IMAGE_NAME)); + connect(m_pBtnRefreshIndex,SIGNAL(clicked()),this,SLOT(refreshIndex())); + m_pBtnRefreshIndex->setToolTip(__tr2qs("Refresh index") ); + + m_pIndexListWidget = new KviTalListWidget(m_pIndexTab); + connect(m_pIndexListWidget,SIGNAL(itemActivated(QListWidgetItem *)),this,SLOT(indexSelected (QListWidgetItem * ))); + + m_pSearchTab = new KviTalVBox(m_pTabWidget); + m_pTabWidget->addTab(m_pSearchTab,__tr2qs("Search")); + + m_pTermsEdit = new QLineEdit(m_pSearchTab); + + connect( m_pTermsEdit, SIGNAL( returnPressed() ), + this, SLOT( startSearch() ) ); + + m_pResultBox = new KviTalListWidget(m_pSearchTab); + connect(m_pResultBox,SIGNAL(itemActivated(QListWidgetItem *)),this,SLOT(searchSelected (QListWidgetItem *))); + + QList li; + li.append(width()-80); + li.append(80); + m_pSplitter->setSizes(li); + + connect(g_pDocIndex, SIGNAL(indexingStart(int)), this, SLOT(indexingStart(int))); + connect(g_pDocIndex, SIGNAL(indexingProgress(int)), this, SLOT(indexingProgress(int))); + connect(g_pDocIndex, SIGNAL(indexingEnd()), this, SLOT(indexingEnd())); + + QTimer::singleShot(0,this,SLOT(initialSetup())); +} + +HelpWindow::~HelpWindow() +{ + g_pHelpWindowList->removeRef(this); +} + +void HelpWindow::initialSetup() +{ + m_pIndexSearch->setFocus(); + + if(!g_bIndexingDone) + { + g_bIndexingDone=TRUE; + QString szDoclist,szDict; + + g_pApp->getLocalKvircDirectory(szDoclist,KviApplication::Help,"help.doclist." KVI_SOURCES_DATE); + g_pApp->getLocalKvircDirectory(szDict,KviApplication::Help,"help.dict." KVI_SOURCES_DATE); + + if ( QFileInfo( szDoclist ).exists() && QFileInfo( szDict ).exists() ) { + g_pDocIndex->readDict(); + m_pIndexListWidget->clear(); + QStringList docList=g_pDocIndex->titlesList(); + m_pIndexListWidget->addItems(docList); + m_pIndexListWidget->sortItems(); + m_pBtnRefreshIndex->setEnabled(true); + } else { + g_pDocIndex->makeIndex(); + } + } +} + +void HelpWindow::indexingStart( int iNum ) +{ + m_pBtnRefreshIndex->setEnabled(false); + m_pBottomLayout->setVisible(true); + m_pProgressBar->setRange(0, iNum); + m_pProgressBar->setValue(0); +} +void HelpWindow::indexingProgress( int iNum ) +{ + m_pProgressBar->setValue(iNum); +} + +void HelpWindow::indexingEnd() +{ + m_pProgressBar->setValue(0); + m_pBottomLayout->setVisible(false); + g_pDocIndex->writeDict(); + m_pIndexListWidget->clear(); + QStringList docList=g_pDocIndex->titlesList(); + m_pIndexListWidget->addItems(docList); + m_pIndexListWidget->sortItems(); + m_pBtnRefreshIndex->setEnabled(true); +} + +void HelpWindow::saveProperties(KviConfigurationFile *cfg) +{ + KviWindow::saveProperties(cfg); + cfg->writeEntry("Splitter",m_pSplitter->sizes()); +} + +void HelpWindow::loadProperties(KviConfigurationFile *cfg) +{ + QList def; + int w = width(); + def.append((w * 82) / 100); + def.append((w * 18) / 100); + m_pSplitter->setSizes(cfg->readIntListEntry("Splitter",def)); + KviWindow::loadProperties(cfg); +} + +void HelpWindow::refreshIndex() +{ + g_pDocIndex->makeIndex(); +} + +void HelpWindow::startSearch() +{ + QString str = m_pTermsEdit->text(); + str = str.replace( "\'", "\"" ); + str = str.replace( "`", "\"" ); + QString buf = str; + str = str.replace( "-", " " ); + str = str.replace( QRegExp( "\\s[\\S]?\\s" ), " " ); + m_terms = str.split(" ",QString::SkipEmptyParts); + QStringList termSeq; + QStringList seqWords; + QStringList::iterator it = m_terms.begin(); + for ( ; it != m_terms.end(); ++it ) { + (*it) = (*it).simplified(); + (*it) = (*it).toLower(); + (*it) = (*it).replace( "\"", "" ); + } + if ( str.contains( '\"' ) ) { + if ( (str.count( '\"' ))%2 == 0 ) { + int beg = 0; + int end = 0; + QString s; + beg = str.indexOf( '\"', beg ); + while ( beg != -1 ) { + beg++; + end = str.indexOf( '\"', beg ); + s = str.mid( beg, end - beg ); + s = s.toLower(); + s = s.simplified(); + if ( s.contains( '*' ) ) { + QMessageBox::warning( this, tr( "Full Text Search" ), + tr( "Using a wildcard within phrases is not allowed." ) ); + return; + } + seqWords += s.split( ' ', QString::SkipEmptyParts ); + termSeq << s; + beg = str.indexOf( '\"', end + 1); + } + } else { + QMessageBox::warning( this, tr( "Full Text Search" ), + tr( "The closing quotation mark is missing." ) ); + return; + } + } + setCursor( Qt::WaitCursor ); + m_foundDocs.clear(); + m_foundDocs = g_pDocIndex->query( m_terms, termSeq, seqWords ); + + m_pResultBox->clear(); + for ( it = m_foundDocs.begin(); it != m_foundDocs.end(); ++it ) + m_pResultBox->addItem( g_pDocIndex->getDocumentTitle( *it ) ); + + m_terms.clear(); + bool isPhrase = FALSE; + QString s = ""; + for ( int i = 0; i < (int)buf.length(); ++i ) { + if ( buf[i] == '\"' ) { + isPhrase = !isPhrase; + s = s.simplified(); + if ( !s.isEmpty() ) + m_terms << s; + s = ""; + } else if ( buf[i] == ' ' && !isPhrase ) { + s = s.simplified(); + if ( !s.isEmpty() ) + m_terms << s; + s = ""; + } else + s += buf[i]; + } + if ( !s.isEmpty() ) m_terms << s; + + setCursor( Qt::ArrowCursor ); +} + +QTextBrowser * HelpWindow::textBrowser() +{ + return m_pHelpWidget->textBrowser(); +} + +void HelpWindow::showIndexTopic() +{ + if (m_pIndexSearch->text().isEmpty()|| !m_pIndexListWidget->selectedItems().count()) return; + int i=g_pDocIndex->titlesList().indexOf(m_pIndexListWidget->selectedItems().at(0)->text()); + textBrowser()->setSource(QUrl(g_pDocIndex->documentList()[ i ])); +} + +void HelpWindow::searchInIndex( const QString &s ) +{ + QListWidgetItem *item ; + QString sl = s.toLower(); + for(int i=0;icount();i++) + { + item=m_pIndexListWidget->item(i); + QString t = item->text(); + if ( t.length() >= sl.length() && + item->text().left(s.length()).toLower() == sl ) { + m_pIndexListWidget->setCurrentItem( item ); + m_pIndexListWidget->scrollToItem(item,QAbstractItemView::PositionAtTop); + break; + } + } +} + +void HelpWindow::indexSelected ( QListWidgetItem *item ) +{ + if (!item) return; + int i=g_pDocIndex->titlesList().indexOf(item->text()); + textBrowser()->setSource(QUrl(g_pDocIndex->documentList()[ i ])); +} + +void HelpWindow::searchSelected ( QListWidgetItem *item ) +{ + if (!item) return; + int i=g_pDocIndex->titlesList().indexOf(item->text()); + textBrowser()->setSource(QUrl(g_pDocIndex->documentList()[ i ])); +} + +QPixmap * HelpWindow::myIconPtr() +{ + return g_pIconManager->getSmallIcon(KVI_SMALLICON_MDIHELP); +} + +void HelpWindow::resizeEvent(QResizeEvent *) +{ + m_pSplitter->setGeometry(0,0,width(),height()); +} + +void HelpWindow::fillCaptionBuffers() +{ + m_szPlainTextCaption = __tr2qs("Help Browser"); +} + + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "HelpWindow.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/help/HelpWindow.h b/src/modules/help/HelpWindow.h new file mode 100644 index 000000000..94eacc347 --- /dev/null +++ b/src/modules/help/HelpWindow.h @@ -0,0 +1,87 @@ +#ifndef _HELPWINDOW_H_ +#define _HELPWINDOW_H_ +//============================================================================= +// +// File : HelpWindow.h +// Creation date : Fri Aug 11 2000 18:05:59 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviWindow.h" +#include "KviCString.h" +#include "KviTalVBox.h" +#include "KviTalListWidget.h" + +#include +#include + +class QProgressBar; +class QPushButton; +class QTextBrowser; +class HelpWidget; + +class HelpWindow : public KviWindow +{ + Q_OBJECT +public: + HelpWindow(KviMainWindow * lpFrm,const char * name); + ~HelpWindow(); +protected: + HelpWidget * m_pHelpWidget; + KviTalVBox * m_pToolBar; + QTabWidget * m_pTabWidget; + KviTalVBox * m_pIndexTab; + KviTalVBox * m_pSearchTab; + KviTalHBox * m_pBottomLayout; + QPushButton * m_pCancelButton; + QProgressBar * m_pProgressBar; + + KviTalListWidget* m_pIndexListWidget; + QLineEdit * m_pIndexSearch; + QStringList m_foundDocs; + QStringList m_terms; + KviTalListWidget* m_pResultBox; + QLineEdit * m_pTermsEdit; + QPushButton * m_pBtnRefreshIndex; +public: + HelpWidget * helpWidget(){ return m_pHelpWidget; }; +protected: + virtual QPixmap * myIconPtr(); + virtual void fillCaptionBuffers(); + virtual void resizeEvent(QResizeEvent *e); + virtual void saveProperties(KviConfigurationFile * cfg); + virtual void loadProperties(KviConfigurationFile * cfg); +public: + QTextBrowser * textBrowser(); +public slots: + void indexSelected ( QListWidgetItem * ); + void searchInIndex( const QString &s ); + void showIndexTopic(); + void startSearch(); + void searchSelected ( QListWidgetItem * ); + void refreshIndex(); + + void initialSetup(); + void indexingStart( int iNum ); + void indexingProgress( int iNum ); + void indexingEnd(); +}; + +#endif //_KVI_HELPWINDOW_H_ diff --git a/src/modules/help/helpwidget.cpp b/src/modules/help/helpwidget.cpp deleted file mode 100644 index 66de43932..000000000 --- a/src/modules/help/helpwidget.cpp +++ /dev/null @@ -1,137 +0,0 @@ -//============================================================================= -// -// File : helpwidget.cpp -// Creation date : Thu Aug 10 2000 17:42:12 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "helpwidget.h" -#include "helpwindow.h" - -#include "KviMainWindow.h" -#include "KviIconManager.h" -#include "KviLocale.h" -#include "KviApplication.h" -#include "KviMessageBox.h" -#include "KviModule.h" -#include "KviFileUtils.h" - -#include -#include -#include -#include -#include -#include - -extern Index * g_pDocIndex; -extern KviPointerList * g_pHelpWindowList; -extern KviPointerList * g_pHelpWidgetList; - -KviHelpWidget::KviHelpWidget(QWidget * par,KviMainWindow *,bool bIsStandalone) -: QWidget(par) -{ - setObjectName("help_widget"); - setMinimumWidth(80); - if(bIsStandalone)g_pHelpWidgetList->append(this); - m_bIsStandalone = bIsStandalone; - - m_pTextBrowser = new QTextBrowser(this); - m_pTextBrowser->setObjectName("text_browser"); - m_pTextBrowser->setFrameStyle(QFrame::StyledPanel|QFrame::Sunken); - m_pTextBrowser->setStyleSheet("QTextBrowser { background-color:white; color:black; }"); - m_pToolBar = new KviTalHBox(this); - - m_pBtnIndex = new QToolButton(m_pToolBar); - m_pBtnIndex->setIcon(*g_pIconManager->getBigIcon(KVI_BIGICON_HELPINDEX)); - connect(m_pBtnIndex,SIGNAL(clicked()),this,SLOT(showIndex())); - - m_pBtnBackward = new QToolButton(m_pToolBar); - m_pBtnBackward->setIcon(*g_pIconManager->getBigIcon(KVI_BIGICON_HELPBACK)); - connect(m_pBtnBackward,SIGNAL(clicked()),m_pTextBrowser,SLOT(backward())); - m_pBtnBackward->setEnabled(false); - - m_pBtnForward = new QToolButton(m_pToolBar); - m_pBtnForward->setIcon(*g_pIconManager->getBigIcon(KVI_BIGICON_HELPFORWARD)); - connect(m_pBtnForward,SIGNAL(clicked()),m_pTextBrowser,SLOT(forward())); - m_pBtnForward->setEnabled(false); - - QWidget* pSpacer=new QWidget(m_pToolBar); - - if(bIsStandalone) - { - QToolButton * b = new QToolButton(m_pToolBar); - b->setIcon(*g_pIconManager->getBigIcon(KVI_BIGICON_HELPCLOSE)); - connect(b,SIGNAL(clicked()),this,SLOT(doClose())); - } - - m_pToolBar->setStretchFactor(pSpacer,1); - connect(m_pTextBrowser,SIGNAL(backwardAvailable(bool)),m_pBtnBackward,SLOT(setEnabled(bool))); - connect(m_pTextBrowser,SIGNAL(forwardAvailable(bool)),m_pBtnForward,SLOT(setEnabled(bool))); -} - -KviHelpWidget::~KviHelpWidget() -{ - if(m_bIsStandalone)g_pHelpWidgetList->removeRef(this); -} - -void KviHelpWidget::showIndex() -{ - QString szHelpDir; - QDir dirHelp; - - g_pApp->getGlobalKvircDirectory(szHelpDir,KviApplication::Help); - dirHelp = QDir(szHelpDir); - - m_pTextBrowser->setSource(QUrl::fromLocalFile(dirHelp.absoluteFilePath("index.html"))); -} - -void KviHelpWidget::resizeEvent(QResizeEvent *) -{ - int hght = m_pToolBar->sizeHint().height(); - if(hght < 40)hght = 40; - m_pToolBar->setGeometry(0,0,width(),hght); - m_pTextBrowser->setGeometry(0,hght,width(),height() - hght); -} - -void KviHelpWidget::doClose() -{ - // hack needed to workaround "QToolBar::emulateButtonClicked()" - // that refers to the "this" pointer after this slot has been - // called (from the "too-small-toolbar-for-all-items-popup") - QTimer::singleShot(0,this,SLOT(suicide())); -} - -void KviHelpWidget::suicide() -{ - // goodbye cruel wolrd - delete this; -} - -QSize KviHelpWidget::sizeHint() const -{ - int wdth = m_pTextBrowser->sizeHint().width(); - if(m_pToolBar->sizeHint().width() > wdth)wdth = m_pToolBar->sizeHint().width(); - QSize s(wdth,m_pTextBrowser->sizeHint().height() + m_pToolBar->sizeHint().height()); - return s; -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "helpwidget.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/help/helpwidget.h b/src/modules/help/helpwidget.h deleted file mode 100644 index 8b6509ef9..000000000 --- a/src/modules/help/helpwidget.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef _HELPWIDGET_H_ -#define _HELPWIDGET_H_ -//============================================================================= -// -// File : helpwidget.h -// Creation date : Thu Aug 10 2000 17:26:20 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "index.h" - -#include "KviTalHBox.h" - -#include -#include - -class QToolButton; -class QLineEdit; -class KviMainWindow; -//class QProcess; - -class KviHelpWidget : public QWidget -{ - Q_OBJECT -public: - KviHelpWidget(QWidget *par,KviMainWindow * lpFrm,bool bIsStandalone = false); - ~KviHelpWidget(); -private: - QToolButton * m_pBtnIndex; - QToolButton * m_pBtnBackward; - QToolButton * m_pBtnForward; - KviTalHBox * m_pToolBar; - QTextBrowser * m_pTextBrowser; - bool m_bIsStandalone; -protected: - virtual void resizeEvent(QResizeEvent *e); -protected slots: - void doClose(); - void showIndex(); - void suicide(); -public: - virtual QSize sizeHint() const; - QTextBrowser * textBrowser() { return m_pTextBrowser; } -}; - - -#endif //_HELPWIDGET_H_ diff --git a/src/modules/help/helpwindow.cpp b/src/modules/help/helpwindow.cpp deleted file mode 100644 index 052d2c6eb..000000000 --- a/src/modules/help/helpwindow.cpp +++ /dev/null @@ -1,322 +0,0 @@ -//============================================================================= -// -// File : helpwindow.cpp -// Creation date : Tue Aug 11 2000 18:08:22 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the m_terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "helpwindow.h" -#include "helpwidget.h" - -#include "KviApplication.h" -#include "KviIconManager.h" -#include "KviOptions.h" -#include "KviLocale.h" -#include "KviModule.h" -#include "KviConfigurationFile.h" -#include "kvi_sourcesdate.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -extern Index * g_pDocIndex; -extern KviPointerList * g_pHelpWindowList; -extern KviPointerList * g_pHelpWidgetList; - -bool g_bIndexingDone = FALSE; -KviHelpWindow::KviHelpWindow(KviMainWindow * lpFrm,const char * name) -: KviWindow(KVI_WINDOW_TYPE_HELP,lpFrm,name) -{ - g_pHelpWindowList->append(this); - m_pSplitter = new KviTalSplitter(Qt::Horizontal,this); - m_pSplitter->setObjectName("main_splitter"); - m_pSplitter->setChildrenCollapsible(false); - - m_pHelpWidget = new KviHelpWidget(m_pSplitter,lpFrm); - - m_pToolBar=new KviTalVBox(m_pSplitter); - m_pTabWidget = new QTabWidget(m_pToolBar); - - m_pBottomLayout = new KviTalHBox(m_pToolBar); - m_pProgressBar = new QProgressBar(m_pBottomLayout); - m_pCancelButton = new QPushButton(m_pBottomLayout); - m_pCancelButton->setText(__tr2qs_ctx("Cancel","logview")); - connect(m_pCancelButton,SIGNAL(clicked()),g_pDocIndex,SLOT(setLastWinClosed())); - m_pBottomLayout->setVisible(false); - - m_pIndexTab = new KviTalVBox(m_pTabWidget); - m_pTabWidget->addTab(m_pIndexTab,__tr2qs("Index")); - - KviTalHBox* pSearchBox = new KviTalHBox(m_pIndexTab); - m_pIndexSearch = new QLineEdit(pSearchBox); - connect( m_pIndexSearch, SIGNAL( textChanged(const QString&) ), - this, SLOT( searchInIndex(const QString&) ) ); - connect( m_pIndexSearch, SIGNAL( returnPressed() ), - this, SLOT( showIndexTopic() ) ); - - m_pBtnRefreshIndex = new QPushButton(pSearchBox); - m_pBtnRefreshIndex->setIcon(*g_pIconManager->getBigIcon(KVI_REFRESH_IMAGE_NAME)); - connect(m_pBtnRefreshIndex,SIGNAL(clicked()),this,SLOT(refreshIndex())); - m_pBtnRefreshIndex->setToolTip(__tr2qs("Refresh index") ); - - m_pIndexListWidget = new KviTalListWidget(m_pIndexTab); - connect(m_pIndexListWidget,SIGNAL(itemActivated(QListWidgetItem *)),this,SLOT(indexSelected (QListWidgetItem * ))); - - m_pSearchTab = new KviTalVBox(m_pTabWidget); - m_pTabWidget->addTab(m_pSearchTab,__tr2qs("Search")); - - m_pTermsEdit = new QLineEdit(m_pSearchTab); - - connect( m_pTermsEdit, SIGNAL( returnPressed() ), - this, SLOT( startSearch() ) ); - - m_pResultBox = new KviTalListWidget(m_pSearchTab); - connect(m_pResultBox,SIGNAL(itemActivated(QListWidgetItem *)),this,SLOT(searchSelected (QListWidgetItem *))); - - QList li; - li.append(width()-80); - li.append(80); - m_pSplitter->setSizes(li); - - connect(g_pDocIndex, SIGNAL(indexingStart(int)), this, SLOT(indexingStart(int))); - connect(g_pDocIndex, SIGNAL(indexingProgress(int)), this, SLOT(indexingProgress(int))); - connect(g_pDocIndex, SIGNAL(indexingEnd()), this, SLOT(indexingEnd())); - - QTimer::singleShot(0,this,SLOT(initialSetup())); -} - -KviHelpWindow::~KviHelpWindow() -{ - g_pHelpWindowList->removeRef(this); -} - -void KviHelpWindow::initialSetup() -{ - m_pIndexSearch->setFocus(); - - if(!g_bIndexingDone) - { - g_bIndexingDone=TRUE; - QString szDoclist,szDict; - - g_pApp->getLocalKvircDirectory(szDoclist,KviApplication::Help,"help.doclist." KVI_SOURCES_DATE); - g_pApp->getLocalKvircDirectory(szDict,KviApplication::Help,"help.dict." KVI_SOURCES_DATE); - - if ( QFileInfo( szDoclist ).exists() && QFileInfo( szDict ).exists() ) { - g_pDocIndex->readDict(); - m_pIndexListWidget->clear(); - QStringList docList=g_pDocIndex->titlesList(); - m_pIndexListWidget->addItems(docList); - m_pIndexListWidget->sortItems(); - m_pBtnRefreshIndex->setEnabled(true); - } else { - g_pDocIndex->makeIndex(); - } - } -} - -void KviHelpWindow::indexingStart( int iNum ) -{ - m_pBtnRefreshIndex->setEnabled(false); - m_pBottomLayout->setVisible(true); - m_pProgressBar->setRange(0, iNum); - m_pProgressBar->setValue(0); -} -void KviHelpWindow::indexingProgress( int iNum ) -{ - m_pProgressBar->setValue(iNum); -} - -void KviHelpWindow::indexingEnd() -{ - m_pProgressBar->setValue(0); - m_pBottomLayout->setVisible(false); - g_pDocIndex->writeDict(); - m_pIndexListWidget->clear(); - QStringList docList=g_pDocIndex->titlesList(); - m_pIndexListWidget->addItems(docList); - m_pIndexListWidget->sortItems(); - m_pBtnRefreshIndex->setEnabled(true); -} - -void KviHelpWindow::saveProperties(KviConfigurationFile *cfg) -{ - KviWindow::saveProperties(cfg); - cfg->writeEntry("Splitter",m_pSplitter->sizes()); -} - -void KviHelpWindow::loadProperties(KviConfigurationFile *cfg) -{ - QList def; - int w = width(); - def.append((w * 82) / 100); - def.append((w * 18) / 100); - m_pSplitter->setSizes(cfg->readIntListEntry("Splitter",def)); - KviWindow::loadProperties(cfg); -} - -void KviHelpWindow::refreshIndex() -{ - g_pDocIndex->makeIndex(); -} - -void KviHelpWindow::startSearch() -{ - QString str = m_pTermsEdit->text(); - str = str.replace( "\'", "\"" ); - str = str.replace( "`", "\"" ); - QString buf = str; - str = str.replace( "-", " " ); - str = str.replace( QRegExp( "\\s[\\S]?\\s" ), " " ); - m_terms = str.split(" ",QString::SkipEmptyParts); - QStringList termSeq; - QStringList seqWords; - QStringList::iterator it = m_terms.begin(); - for ( ; it != m_terms.end(); ++it ) { - (*it) = (*it).simplified(); - (*it) = (*it).toLower(); - (*it) = (*it).replace( "\"", "" ); - } - if ( str.contains( '\"' ) ) { - if ( (str.count( '\"' ))%2 == 0 ) { - int beg = 0; - int end = 0; - QString s; - beg = str.indexOf( '\"', beg ); - while ( beg != -1 ) { - beg++; - end = str.indexOf( '\"', beg ); - s = str.mid( beg, end - beg ); - s = s.toLower(); - s = s.simplified(); - if ( s.contains( '*' ) ) { - QMessageBox::warning( this, tr( "Full Text Search" ), - tr( "Using a wildcard within phrases is not allowed." ) ); - return; - } - seqWords += s.split( ' ', QString::SkipEmptyParts ); - termSeq << s; - beg = str.indexOf( '\"', end + 1); - } - } else { - QMessageBox::warning( this, tr( "Full Text Search" ), - tr( "The closing quotation mark is missing." ) ); - return; - } - } - setCursor( Qt::WaitCursor ); - m_foundDocs.clear(); - m_foundDocs = g_pDocIndex->query( m_terms, termSeq, seqWords ); - - m_pResultBox->clear(); - for ( it = m_foundDocs.begin(); it != m_foundDocs.end(); ++it ) - m_pResultBox->addItem( g_pDocIndex->getDocumentTitle( *it ) ); - - m_terms.clear(); - bool isPhrase = FALSE; - QString s = ""; - for ( int i = 0; i < (int)buf.length(); ++i ) { - if ( buf[i] == '\"' ) { - isPhrase = !isPhrase; - s = s.simplified(); - if ( !s.isEmpty() ) - m_terms << s; - s = ""; - } else if ( buf[i] == ' ' && !isPhrase ) { - s = s.simplified(); - if ( !s.isEmpty() ) - m_terms << s; - s = ""; - } else - s += buf[i]; - } - if ( !s.isEmpty() ) m_terms << s; - - setCursor( Qt::ArrowCursor ); -} - -QTextBrowser * KviHelpWindow::textBrowser() -{ - return m_pHelpWidget->textBrowser(); -} - -void KviHelpWindow::showIndexTopic() -{ - if (m_pIndexSearch->text().isEmpty()|| !m_pIndexListWidget->selectedItems().count()) return; - int i=g_pDocIndex->titlesList().indexOf(m_pIndexListWidget->selectedItems().at(0)->text()); - textBrowser()->setSource(QUrl(g_pDocIndex->documentList()[ i ])); -} - -void KviHelpWindow::searchInIndex( const QString &s ) -{ - QListWidgetItem *item ; - QString sl = s.toLower(); - for(int i=0;icount();i++) - { - item=m_pIndexListWidget->item(i); - QString t = item->text(); - if ( t.length() >= sl.length() && - item->text().left(s.length()).toLower() == sl ) { - m_pIndexListWidget->setCurrentItem( item ); - m_pIndexListWidget->scrollToItem(item,QAbstractItemView::PositionAtTop); - break; - } - } -} - -void KviHelpWindow::indexSelected ( QListWidgetItem *item ) -{ - if (!item) return; - int i=g_pDocIndex->titlesList().indexOf(item->text()); - textBrowser()->setSource(QUrl(g_pDocIndex->documentList()[ i ])); -} - -void KviHelpWindow::searchSelected ( QListWidgetItem *item ) -{ - if (!item) return; - int i=g_pDocIndex->titlesList().indexOf(item->text()); - textBrowser()->setSource(QUrl(g_pDocIndex->documentList()[ i ])); -} - -QPixmap * KviHelpWindow::myIconPtr() -{ - return g_pIconManager->getSmallIcon(KVI_SMALLICON_MDIHELP); -} - -void KviHelpWindow::resizeEvent(QResizeEvent *) -{ - m_pSplitter->setGeometry(0,0,width(),height()); -} - -void KviHelpWindow::fillCaptionBuffers() -{ - m_szPlainTextCaption = __tr2qs("Help Browser"); -} - - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "helpwindow.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/help/helpwindow.h b/src/modules/help/helpwindow.h deleted file mode 100644 index 8b262273c..000000000 --- a/src/modules/help/helpwindow.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef _HELPWINDOW_H_ -#define _HELPWINDOW_H_ -//============================================================================= -// -// File : helpwindow.h -// Creation date : Fri Aug 11 2000 18:05:59 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "KviWindow.h" -#include "KviCString.h" -#include "KviTalVBox.h" -#include "KviTalListWidget.h" - -#include -#include - -class QProgressBar; -class QPushButton; -class QTextBrowser; -class KviHelpWidget; - -class KviHelpWindow : public KviWindow -{ - Q_OBJECT -public: - KviHelpWindow(KviMainWindow * lpFrm,const char * name); - ~KviHelpWindow(); -protected: - KviHelpWidget * m_pHelpWidget; - KviTalVBox * m_pToolBar; - QTabWidget * m_pTabWidget; - KviTalVBox * m_pIndexTab; - KviTalVBox * m_pSearchTab; - KviTalHBox * m_pBottomLayout; - QPushButton * m_pCancelButton; - QProgressBar * m_pProgressBar; - - KviTalListWidget* m_pIndexListWidget; - QLineEdit * m_pIndexSearch; - QStringList m_foundDocs; - QStringList m_terms; - KviTalListWidget* m_pResultBox; - QLineEdit * m_pTermsEdit; - QPushButton * m_pBtnRefreshIndex; -public: - KviHelpWidget * helpWidget(){ return m_pHelpWidget; }; -protected: - virtual QPixmap * myIconPtr(); - virtual void fillCaptionBuffers(); - virtual void resizeEvent(QResizeEvent *e); - virtual void saveProperties(KviConfigurationFile * cfg); - virtual void loadProperties(KviConfigurationFile * cfg); -public: - QTextBrowser * textBrowser(); -public slots: - void indexSelected ( QListWidgetItem * ); - void searchInIndex( const QString &s ); - void showIndexTopic(); - void startSearch(); - void searchSelected ( QListWidgetItem * ); - void refreshIndex(); - - void initialSetup(); - void indexingStart( int iNum ); - void indexingProgress( int iNum ); - void indexingEnd(); -}; - -#endif //_KVI_HELPWINDOW_H_ diff --git a/src/modules/help/index.cpp b/src/modules/help/index.cpp deleted file mode 100644 index 0bd2a0033..000000000 --- a/src/modules/help/index.cpp +++ /dev/null @@ -1,602 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the Qt Assistant of the Qt Toolkit. -** -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information -** to ensure GNU General Public Licensing requirements will be met: -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. In addition, as a special -** exception, Nokia gives you certain additional rights. These rights -** are described in the Nokia Qt GPL Exception version 1.3, included in -** the file GPL_EXCEPTION.txt in this package. -** -** Qt for Windows(R) Licensees -** As a special exception, Nokia, as the sole copyright holder for Qt -** Designer, grants users of the Qt/Eclipse Integration plug-in the -** right for the Qt/Eclipse Integration to link to functionality -** provided by Qt Designer and its related libraries. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** -****************************************************************************/ - -#include "index.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -struct Term { - Term() : frequency(-1) {} - Term( const QString &t, int f, QVector l ) : term( t ), frequency( f ), documents( l ) {} - QString term; - int frequency; - QVectordocuments; - bool operator<( const Term &i2 ) const { return frequency < i2.frequency; } -}; - -QDataStream &operator>>( QDataStream &s, Document &l ) -{ - s >> l.docNumber; - s >> l.frequency; - return s; -} - -QDataStream &operator<<( QDataStream &s, const Document &l ) -{ - s << (qint16)l.docNumber; - s << (qint16)l.frequency; - return s; -} - -Index::Index( const QString &dp, const QString &hp ) - : QObject( 0 ), docPath( dp ) -{ - Q_UNUSED(hp); - - alreadyHaveDocList = false; - lastWindowClosed = false; - connect( qApp, SIGNAL(lastWindowClosed()), - this, SLOT(setLastWinClosed()) ); - - m_pTimer = new QTimer(this); - m_pTimer->setSingleShot(true); - m_pTimer->setInterval(0); - connect(m_pTimer, SIGNAL(timeout()), this, SLOT(filterNext())); -} - -Index::Index( const QStringList &dl, const QString &hp ) - : QObject( 0 ) -{ - Q_UNUSED(hp); - docList = dl; - alreadyHaveDocList = true; - lastWindowClosed = false; - connect( qApp, SIGNAL(lastWindowClosed()), - this, SLOT(setLastWinClosed()) ); -} - -void Index::setLastWinClosed() -{ - lastWindowClosed = true; -} - -void Index::setDictionaryFile( const QString &f ) -{ - dictFile = f; -} - -void Index::setDocListFile( const QString &f ) -{ - docListFile = f; -} - -void Index::setDocList( const QStringList &lst ) -{ - docList = lst; -} - -void Index::makeIndex() -{ - if ( !alreadyHaveDocList ) - setupDocumentList(); - - lastWindowClosed = false; - emit indexingStart( docList.count() ); - dict.clear(); - m_iCurItem = 0; - m_pTimer->start(); //singleshot -} - -void Index::filterNext() -{ - if(m_iCurItem < docList.count() && !lastWindowClosed) - { - QUrl url(docList.at(m_iCurItem)); - parseDocument( url.toLocalFile(), m_iCurItem ); - emit indexingProgress( m_iCurItem ); - m_iCurItem++; - m_pTimer->start(); //singleshot - } else { - emit indexingEnd(); - } -} - -void Index::setupDocumentList() -{ - docList.clear(); - titleList.clear(); - QDir d( docPath ); - QStringList filters; - filters.append(QLatin1String("*.html")); - QStringList lst = d.entryList(filters); - QStringList::ConstIterator it = lst.constBegin(); - for ( ; it != lst.constEnd(); ++it ) - { - QString filename=QLatin1String("file:") + docPath + QLatin1String("/") + *it ; - docList.append(filename); - titleList.append(getDocumentTitle(filename)); - } -} - -void Index::insertInDict( const QString &str, int docNum ) -{ - if ( str == QLatin1String("amp") || str == QLatin1String("nbsp")) - return; - Entry *e = 0; - if ( dict.count() ) - e = dict[ str ]; - - if ( e ) { - if ( e->documents.last().docNumber != docNum ) - e->documents.append( Document(docNum, 1 ) ); - else - e->documents.last().frequency++; - } else { - dict.insert( str, new Entry( docNum ) ); - } -} - -QString Index::getCharsetForDocument(QFile *file) -{ - QTextStream s(file); - QString contents = s.readAll(); - - QString encoding; - int start = contents.indexOf(QLatin1String(" 0) { - int end = contents.indexOf(QLatin1String(">"), start); - QString meta = contents.mid(start+5, end-start); - meta = meta.toLower(); - QRegExp r(QLatin1String("charset=([^\"\\s]+)")); - if (r.indexIn(meta) != -1) { - encoding = r.cap(1); - } - } - - file->seek(0); - if (encoding.isEmpty()) - return QLatin1String("utf-8"); - return encoding; -} - -void Index::parseDocument( const QString &filename, int docNum ) -{ - QFile file( filename ); - if ( !file.open(QFile::ReadOnly) ) { - qWarning( "can not open file %s", qPrintable(filename) ); - return; - } - - QTextStream s(&file); - QString en = getCharsetForDocument(&file); - s.setCodec(QTextCodec::codecForName(en.toLatin1().constData())); - - QString text = s.readAll(); - if (text.isNull()) - return; - - bool valid = true; - const QChar *buf = text.unicode(); - QChar str[64]; - QChar c = buf[0]; - int j = 0; - int i = 0; - while ( j < text.length() ) { - if ( c == QLatin1Char('<') || c == QLatin1Char('&') ) { - valid = false; - if ( i > 1 ) - insertInDict( QString(str,i), docNum ); - i = 0; - c = buf[++j]; - continue; - } - if ( ( c == QLatin1Char('>') || c == QLatin1Char(';') ) && !valid ) { - valid = true; - c = buf[++j]; - continue; - } - if ( !valid ) { - c = buf[++j]; - continue; - } - if ( ( c.isLetterOrNumber() || c == QLatin1Char('_') ) && i < 63 ) { - str[i] = c.toLower(); - ++i; - } else { - if ( i > 1 ) - insertInDict( QString(str,i), docNum ); - i = 0; - } - c = buf[++j]; - } - if ( i > 1 ) - insertInDict( QString(str,i), docNum ); - file.close(); -} - -void Index::writeDict() -{ - QFile f( dictFile ); - if ( !f.open(QFile::WriteOnly ) ) - return; - QDataStream s( &f ); - for(QHash::Iterator it = dict.begin(); it != dict.end(); ++it) { - s << it.key(); - s << it.value()->documents.count(); - s << it.value()->documents; - } - f.close(); - writeDocumentList(); -} - -void Index::writeDocumentList() -{ - QFile f( docListFile ); - if ( !f.open(QFile::WriteOnly ) ) - return; - QDataStream s( &f ); - s << docList; - - QFile f1( docListFile+".titles" ); - if ( !f1.open(QFile::WriteOnly ) ) - return; - QDataStream s1( &f1 ); - s1 << titleList; - -} - -void Index::readDict() -{ - QFile f( dictFile ); - if ( !f.open(QFile::ReadOnly ) ) - return; - - dict.clear(); - QDataStream s( &f ); - QString key; - int numOfDocs; - QVector docs; - while ( !s.atEnd() ) { - s >> key; - s >> numOfDocs; - docs.resize(numOfDocs); - s >> docs; - dict.insert( key, new Entry( docs ) ); - } - f.close(); - readDocumentList(); -} - -void Index::readDocumentList() -{ - QFile f( docListFile ); - if ( !f.open(QFile::ReadOnly ) ) - return; - QDataStream s( &f ); - s >> docList; - QFile f1( docListFile+".titles" ); - if ( !f1.open(QFile::ReadOnly ) ) - return; - QDataStream s1( &f1 ); - s1 >> titleList; -} - -QStringList Index::query( const QStringList &terms, const QStringList &termSeq, const QStringList &seqWords ) -{ - QList termList; - for (QStringList::ConstIterator it = terms.begin(); it != terms.end(); ++it ) { - Entry *e = 0; - if ( (*it).contains(QLatin1Char('*')) ) { - QVector wcts = setupDummyTerm( getWildcardTerms( *it ) ); - termList.append( Term(QLatin1String("dummy"), wcts.count(), wcts ) ); - } else if ( dict[ *it ] ) { - e = dict[ *it ]; - termList.append( Term( *it, e->documents.count(), e->documents ) ); - } else { - return QStringList(); - } - } - if ( !termList.count() ) - return QStringList(); - qSort(termList); - - QVector minDocs = termList.takeFirst().documents; - for(QList::Iterator it = termList.begin(); it != termList.end(); ++it) { - Term *t = &(*it); - QVector docs = t->documents; - for(QVector::Iterator minDoc_it = minDocs.begin(); minDoc_it != minDocs.end(); ) { - bool found = false; - for (QVector::ConstIterator doc_it = docs.constBegin(); doc_it != docs.constEnd(); ++doc_it ) { - if ( (*minDoc_it).docNumber == (*doc_it).docNumber ) { - (*minDoc_it).frequency += (*doc_it).frequency; - found = true; - break; - } - } - if ( !found ) - minDoc_it = minDocs.erase( minDoc_it ); - else - ++minDoc_it; - } - } - - QStringList results; - qSort( minDocs ); - if ( termSeq.isEmpty() ) { - for(QVector::Iterator it = minDocs.begin(); it != minDocs.end(); ++it) - results << docList.at((int)(*it).docNumber); - return results; - } - - QString fileName; - for(QVector::Iterator it = minDocs.begin(); it != minDocs.end(); ++it) { - fileName = docList[ (int)(*it).docNumber ]; - if ( searchForPattern( termSeq, seqWords, fileName ) ) - results << fileName; - } - return results; -} - -QString Index::getDocumentTitle( const QString &fullFileName ) -{ - QUrl url(fullFileName); - QString fileName = url.toLocalFile(); - - if (documentTitleCache.contains(fileName)) - return documentTitleCache.value(fileName); - - QFile file( fileName ); - if ( !file.open( QFile::ReadOnly ) ) { - qWarning( "cannot open file %s", qPrintable(fileName) ); - return fileName; - } - QTextStream s( &file ); - QString text = s.readAll(); - - int start = text.indexOf(QLatin1String(""), 0, Qt::CaseInsensitive) + 7; - int end = text.indexOf(QLatin1String(""), 0, Qt::CaseInsensitive); - - QString title = tr("Untitled"); - if (end - start > 0) { - title = text.mid(start, end - start); - if (Qt::mightBeRichText(title)) { - QTextDocument doc; - doc.setHtml(title); - title = doc.toPlainText(); - } - } - documentTitleCache.insert(fileName, title); - return title; -} - -QStringList Index::getWildcardTerms( const QString &term ) -{ - QStringList lst; - QStringList terms = split( term ); - QStringList::Iterator iter; - - for(QHash::Iterator it = dict.begin(); it != dict.end(); ++it) { - int index = 0; - bool found = false; - QString text( it.key() ); - for ( iter = terms.begin(); iter != terms.end(); ++iter ) { - if ( *iter == QLatin1String("*") ) { - found = true; - continue; - } - if ( iter == terms.begin() && (*iter)[0] != text[0] ) { - found = false; - break; - } - index = text.indexOf( *iter, index ); - if ( *iter == terms.last() && index != (int)text.length()-1 ) { - index = text.lastIndexOf( *iter ); - if ( index != (int)text.length() - (int)(*iter).length() ) { - found = false; - break; - } - } - if ( index != -1 ) { - found = true; - index += (*iter).length(); - continue; - } else { - found = false; - break; - } - } - if ( found ) - lst << text; - } - - return lst; -} - -QStringList Index::split( const QString &str ) -{ - QStringList lst; - int j = 0; - int i = str.indexOf(QLatin1Char('*'), j ); - - if (str.startsWith(QLatin1String("*"))) - lst << QLatin1String("*"); - - while ( i != -1 ) { - if ( i > j && i <= (int)str.length() ) { - lst << str.mid( j, i - j ); - lst << QLatin1String("*"); - } - j = i + 1; - i = str.indexOf(QLatin1Char('*'), j ); - } - - int l = str.length() - 1; - if ( str.mid( j, l - j + 1 ).length() > 0 ) - lst << str.mid( j, l - j + 1 ); - - return lst; -} - -QVector Index::setupDummyTerm( const QStringList &terms ) -{ - QList termList; - for (QStringList::ConstIterator it = terms.begin(); it != terms.end(); ++it) { - Entry *e = 0; - if ( dict[ *it ] ) { - e = dict[ *it ]; - termList.append( Term( *it, e->documents.count(), e->documents ) ); - } - } - QVector maxList(0); - if ( !termList.count() ) - return maxList; - qSort(termList); - - maxList = termList.takeLast().documents; - for(QList::Iterator it = termList.begin(); it != termList.end(); ++it) { - Term *t = &(*it); - QVector docs = t->documents; - for (QVector::iterator docIt = docs.begin(); docIt != docs.end(); ++docIt ) { - if ( maxList.indexOf( *docIt ) == -1 ) - maxList.append( *docIt ); - } - } - return maxList; -} - -void Index::buildMiniDict( const QString &str ) -{ - if ( miniDict[ str ] ) - miniDict[ str ]->positions.append( wordNum ); - ++wordNum; -} - -bool Index::searchForPattern( const QStringList &patterns, const QStringList &words, const QString &fileName ) -{ - QUrl url(fileName); - QString fName = url.toLocalFile(); - QFile file( fName ); - if ( !file.open( QFile::ReadOnly ) ) { - qWarning( "cannot open file %s", qPrintable(fName) ); - return false; - } - - wordNum = 3; - miniDict.clear(); - QStringList::ConstIterator cIt = words.begin(); - for ( ; cIt != words.end(); ++cIt ) - miniDict.insert( *cIt, new PosEntry( 0 ) ); - - QTextStream s( &file ); - QString text = s.readAll(); - bool valid = true; - const QChar *buf = text.unicode(); - QChar str[64]; - QChar c = buf[0]; - int j = 0; - int i = 0; - while ( j < text.length() ) { - if ( c == QLatin1Char('<') || c == QLatin1Char('&') ) { - valid = false; - if ( i > 1 ) - buildMiniDict( QString(str,i) ); - i = 0; - c = buf[++j]; - continue; - } - if ( ( c == QLatin1Char('>') || c == QLatin1Char(';') ) && !valid ) { - valid = true; - c = buf[++j]; - continue; - } - if ( !valid ) { - c = buf[++j]; - continue; - } - if ( ( c.isLetterOrNumber() || c == QLatin1Char('_') ) && i < 63 ) { - str[i] = c.toLower(); - ++i; - } else { - if ( i > 1 ) - buildMiniDict( QString(str,i) ); - i = 0; - } - c = buf[++j]; - } - if ( i > 1 ) - buildMiniDict( QString(str,i) ); - file.close(); - - QStringList::ConstIterator patIt = patterns.begin(); - QStringList wordLst; - QList a, b; - QList::iterator aIt; - for ( ; patIt != patterns.end(); ++patIt ) { - wordLst = (*patIt).split(QLatin1Char(' ')); - a = miniDict[ wordLst[0] ]->positions; - for ( int j = 1; j < (int)wordLst.count(); ++j ) { - b = miniDict[ wordLst[j] ]->positions; - aIt = a.begin(); - while ( aIt != a.end() ) { - if ( b.contains( *aIt + 1 )) { - (*aIt)++; - ++aIt; - } else { - aIt = a.erase( aIt ); - } - } - } - } - if ( a.count() ) - return true; - return false; -} - -QT_END_NAMESPACE diff --git a/src/modules/help/index.h b/src/modules/help/index.h deleted file mode 100644 index 3d5970645..000000000 --- a/src/modules/help/index.h +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the Qt Assistant of the Qt Toolkit. -** -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information -** to ensure GNU General Public Licensing requirements will be met: -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. In addition, as a special -** exception, Nokia gives you certain additional rights. These rights -** are described in the Nokia Qt GPL Exception version 1.3, included in -** the file GPL_EXCEPTION.txt in this package. -** -** Qt for Windows(R) Licensees -** As a special exception, Nokia, as the sole copyright holder for Qt -** Designer, grants users of the Qt/Eclipse Integration plug-in the -** right for the Qt/Eclipse Integration to link to functionality -** provided by Qt Designer and its related libraries. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** -****************************************************************************/ - -#ifndef INDEX_H -#define INDEX_H - -#include -#include -#include -#include -#include -#include -#include - -class QTimer; - -QT_BEGIN_NAMESPACE - -struct Document { - Document( int d, int f ) : docNumber( d ), frequency( f ) {} - Document() : docNumber( -1 ), frequency( 0 ) {} - bool operator==( const Document &doc ) const { - return docNumber == doc.docNumber; - } - bool operator<( const Document &doc ) const { - return frequency > doc.frequency; - } - bool operator<=( const Document &doc ) const { - return frequency >= doc.frequency; - } - bool operator>( const Document &doc ) const { - return frequency < doc.frequency; - } - qint16 docNumber; - qint16 frequency; -}; - -QDataStream &operator>>( QDataStream &s, Document &l ); -QDataStream &operator<<( QDataStream &s, const Document &l ); - -class Index : public QObject -{ - Q_OBJECT -public: - struct Entry { - Entry( int d ) { documents.append( Document( d, 1 ) ); } - Entry( QVector l ) : documents( l ) {} - QVector documents; - }; - struct PosEntry { - PosEntry( int p ) { positions.append( p ); } - QList positions; - }; - - Index( const QString &dp, const QString &hp ); - Index( const QStringList &dl, const QString &hp ); - void writeDict(); - void readDict(); - void makeIndex(); - QStringList query( const QStringList&, const QStringList&, const QStringList& ); - QString getDocumentTitle( const QString& ); - void setDictionaryFile( const QString& ); - void setDocListFile( const QString& ); - void setDocList( const QStringList & ); - - const QStringList& documentList() { return docList; }; - const QStringList& titlesList() { return titleList; }; - -signals: - void indexingStart( int ); - void indexingProgress( int ); - void indexingEnd(); - -private slots: - void setLastWinClosed(); - void filterNext(); -private: - void setupDocumentList(); - void parseDocument( const QString&, int ); - void insertInDict( const QString&, int ); - void writeDocumentList(); - void readDocumentList(); - QStringList getWildcardTerms( const QString& ); - QStringList split( const QString& ); - QVector setupDummyTerm( const QStringList& ); - bool searchForPattern( const QStringList&, const QStringList&, const QString& ); - void buildMiniDict( const QString& ); - QString getCharsetForDocument(QFile *); - QStringList docList; - QStringList titleList; - QHash dict; - QHash miniDict; - uint wordNum; - QString docPath; - QString dictFile, docListFile; - bool alreadyHaveDocList; - bool lastWindowClosed; - QHash documentTitleCache; - QTimer * m_pTimer; - int m_iCurItem; -}; - -#endif - -QT_END_NAMESPACE diff --git a/src/modules/help/libkvihelp.cpp b/src/modules/help/libkvihelp.cpp index 8cf269cbd..039d4fbef 100644 --- a/src/modules/help/libkvihelp.cpp +++ b/src/modules/help/libkvihelp.cpp @@ -22,9 +22,9 @@ // //============================================================================= -#include "helpwidget.h" -#include "helpwindow.h" -#include "index.h" +#include "HelpWidget.h" +#include "HelpWindow.h" +#include "HelpIndex.h" #include "KviLocale.h" #include "KviModule.h" #include "KviFileUtils.h" @@ -36,9 +36,9 @@ #include #include -Index * g_pDocIndex = 0; -KviPointerList * g_pHelpWidgetList = 0; -KviPointerList * g_pHelpWindowList = 0; +HelpIndex * g_pDocIndex = 0; +KviPointerList * g_pHelpWidgetList = 0; +KviPointerList * g_pHelpWindowList = 0; /* @doc: help.open @@ -177,7 +177,7 @@ static bool help_kvs_cmd_open(KviKvsModuleCommandCall * c) if(!c->switches()->find('n',"new")) { - KviHelpWidget * w = (KviHelpWidget *)c->window()->frame()->findChild("help_widget"); + HelpWidget * w = (HelpWidget *)c->window()->frame()->findChild("help_widget"); if(w) { @@ -187,11 +187,11 @@ static bool help_kvs_cmd_open(KviKvsModuleCommandCall * c) } if(c->switches()->find('m',"mdi")) { - KviHelpWindow *w = new KviHelpWindow(c->window()->frame(),"Help browser"); + HelpWindow *w = new HelpWindow(c->window()->frame(),"Help browser"); w->textBrowser()->setSource(QUrl::fromLocalFile(f.absoluteFilePath())); c->window()->frame()->addWindow(w); } else { - KviHelpWidget *w = new KviHelpWidget(c->window()->frame()->splitter(), + HelpWidget *w = new HelpWidget(c->window()->frame()->splitter(), c->window()->frame(),true); w->textBrowser()->setSource(QUrl::fromLocalFile(f.absoluteFilePath())); w->show(); @@ -207,15 +207,15 @@ static bool help_module_init(KviModule * m) g_pApp->getLocalKvircDirectory(szDocList,KviApplication::Help,"help.doclist." KVI_SOURCES_DATE); g_pApp->getGlobalKvircDirectory(szHelpDir,KviApplication::Help); - g_pDocIndex = new Index(szHelpDir,szDocList); + g_pDocIndex = new HelpIndex(szHelpDir,szDocList); g_pDocIndex->setDocListFile(szDocList); g_pApp->getLocalKvircDirectory(szHelpDir,KviApplication::Help,"help.dict." KVI_SOURCES_DATE); g_pDocIndex->setDictionaryFile(szHelpDir); - g_pHelpWidgetList = new KviPointerList; + g_pHelpWidgetList = new KviPointerList; g_pHelpWidgetList->setAutoDelete(false); - g_pHelpWindowList = new KviPointerList; + g_pHelpWindowList = new KviPointerList; g_pHelpWindowList->setAutoDelete(false); KVSM_REGISTER_SIMPLE_COMMAND(m,"open",help_kvs_cmd_open); diff --git a/src/modules/http/CMakeLists.txt b/src/modules/http/CMakeLists.txt index b3a48e052..29ce4f8f1 100644 --- a/src/modules/http/CMakeLists.txt +++ b/src/modules/http/CMakeLists.txt @@ -1,12 +1,12 @@ # CMakeLists for src/modules/http SET(kvihttp_MOC_HDRS - httpfiletransfer.h + HttpFileTransfer.h ) SET(kvihttp_SRCS libkvihttp.cpp - httpfiletransfer.cpp + HttpFileTransfer.cpp ) SET(files diff --git a/src/modules/http/HttpFileTransfer.cpp b/src/modules/http/HttpFileTransfer.cpp new file mode 100644 index 000000000..2e63b1aa1 --- /dev/null +++ b/src/modules/http/HttpFileTransfer.cpp @@ -0,0 +1,493 @@ +//============================================================================= +// +// File : HttpFileTransfer.h +// Creation date : Tue Apr 22 2003 02:00:12 GMT by Szymon Stefanek +// +// This config is part of the KVIrc irc client distribution +// Copyright (C) 2003-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "HttpFileTransfer.h" + +#include "KviApplication.h" +#include "kvi_out.h" +#include "KviLocale.h" +#include "KviWindow.h" +#include "KviIconManager.h" +#include "KviNetUtils.h" +#include "KviKvsEventTriggers.h" +#include "KviConsoleWindow.h" +#include "KviKvsScript.h" +#include "KviTalPopupMenu.h" + +#include + +static KviPointerList * g_pHttpFileTransfers = 0; +static QPixmap * g_pHttpIcon = 0; + + +HttpFileTransfer::HttpFileTransfer() +: KviFileTransfer() +{ + init(); // ensure we're initialized + g_pHttpFileTransfers->append(this); + + m_tStartTime = kvi_unixTime(); + m_tTransferStartTime = 0; + m_tTransferEndTime = 0; + + m_bNotifyCompletion = true; + m_bAutoClean = false; + m_pAutoCleanTimer = 0; + m_bNoOutput = false; + + m_pHttpRequest = new KviHttpRequest(); + + connect(m_pHttpRequest,SIGNAL(status(const QString &)),this,SLOT(statusMessage(const QString &))); + connect(m_pHttpRequest,SIGNAL(terminated(bool)),this,SLOT(transferTerminated(bool))); + connect(m_pHttpRequest,SIGNAL(header(KviPointerHashTable *)),this,SLOT(headersReceived(KviPointerHashTable *))); + connect(m_pHttpRequest,SIGNAL(resolvingHost(const QString &)),this,SLOT(resolvingHost(const QString &))); + connect(m_pHttpRequest,SIGNAL(requestSent(const QStringList &)),this,SLOT(requestSent(const QStringList &))); + connect(m_pHttpRequest,SIGNAL(contactingHost(const QString &)),this,SLOT(contactingHost(const QString &))); + connect(m_pHttpRequest,SIGNAL(receivedResponse(const QString &)),this,SLOT(receivedResponse(const QString &))); + connect(m_pHttpRequest,SIGNAL(connectionEstabilished()),this,SLOT(connectionEstabilished())); + + m_eGeneralStatus = Initializing; + m_szStatusString = __tr2qs_ctx("Initializing","http"); +} + +HttpFileTransfer::~HttpFileTransfer() +{ + g_pHttpFileTransfers->removeRef(this); + delete m_pHttpRequest; + if(m_pAutoCleanTimer) + { + m_pAutoCleanTimer->stop(); + delete m_pAutoCleanTimer; + } +} + +void HttpFileTransfer::autoClean() +{ + killTimer(m_TimerId); + die(); +} + +QString HttpFileTransfer::localFileName() +{ + return m_pHttpRequest->fileName(); +} + +void HttpFileTransfer::abort() +{ + m_pHttpRequest->abort(); +} + +void HttpFileTransfer::fillContextPopup(KviTalPopupMenu * m) +{ + int id = m->insertItem(__tr2qs_ctx("Abort","http"),this,SLOT(abort())); + if(!active())m->setItemEnabled(id,false); +} + +bool HttpFileTransfer::active() +{ + return ((m_eGeneralStatus == Connecting) || (m_eGeneralStatus == Downloading)); +} + +void HttpFileTransfer::displayPaint(QPainter * p,int column, QRect rect) +{ + int width = rect.width(), height = rect.height(); + QString txt; + bool bIsTerminated = ((m_eGeneralStatus == Success) || (m_eGeneralStatus == Failure)); + + switch(column) + { + case COLUMN_TRANSFERTYPE: + { + int offset = 0; + switch(m_eGeneralStatus) + { + case Initializing: + case Connecting: offset = 0; break; + case Downloading: offset = 48; break; + case Success: offset = 96; break; + case Failure: offset = 144; break; + } + if(g_pHttpIcon) + p->drawPixmap(rect.left() + 3, rect.top() + 3,*g_pHttpIcon,offset,0,48,64); + } + break; + case COLUMN_FILEINFO: + { + QFontMetrics fm(p->font()); + + QString szFrom = __tr2qs_ctx("From: ","http"); + QString szTo = __tr2qs_ctx("To: ","http"); + + int daW1 = fm.width(szFrom); + int daW2 = fm.width(szTo); + if(daW1 < daW2)daW1 = daW2; + int iLineSpacing = fm.lineSpacing(); + + p->setPen(Qt::black); + + int iY = rect.top() + 4; + + p->drawText(rect.left() + 4 + daW1,iY,width - (8 + daW1),height - 8,Qt::AlignTop | Qt::AlignLeft,m_pHttpRequest->url().url()); + iY += iLineSpacing; + if(!(m_pHttpRequest->fileName().isEmpty())) + { + p->drawText(rect.left() + 4 + daW1,iY,width - (8 + daW1),height - 8,Qt::AlignTop | Qt::AlignLeft,m_pHttpRequest->fileName()); + } + iY += iLineSpacing; + + + p->setPen(Qt::darkGray); + + p->drawText(rect.left() + 4, rect.top() + 4,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,szFrom); + p->drawText(rect.left() + 4, rect.top() + 4 + iLineSpacing,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,szTo); + + p->setPen(QColor(180,180,200)); + + iLineSpacing += 2; + + p->drawRect(rect.left() + 4, rect.top() + height - (iLineSpacing + 4),width - 8,iLineSpacing); + p->fillRect(rect.left() + 5, rect.top() + height - (iLineSpacing + 3),width - 10,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240)); + p->setPen(Qt::black); + p->drawText(rect.left() + 7, rect.top() + height - (iLineSpacing + 4),width - 14,iLineSpacing,Qt::AlignVCenter | Qt::AlignLeft,m_szStatusString); + } + break; + case COLUMN_PROGRESS: + { + QFontMetrics fm(p->font()); + + unsigned int uTotal = m_pHttpRequest->totalSize(); + unsigned int uRecvd = m_pHttpRequest->receivedSize(); + int iW = width - 8; + + p->setPen(bIsTerminated ? Qt::lightGray : QColor(210,210,240)); + p->drawRect(rect.left() + 4, rect.top() + 4,iW,12); + + int iAvgSpeed = -1; + int iEta = -1; + + if(m_tTransferStartTime > 0) + { + int tSpan = kvi_timeSpan(m_tTransferEndTime > 0 ? m_tTransferEndTime : kvi_unixTime(),m_tTransferStartTime); + if(tSpan > 0) + { + //qDebug("SPAN: %d (%d - %d)",tSpan,m_tTransferEndTime > 0 ? m_tTransferEndTime : kvi_unixTime(),m_tTransferStartTime); + iAvgSpeed = uRecvd / tSpan; + if(!bIsTerminated && (uTotal >= uRecvd)) + { + unsigned int uRemaining = uTotal - uRecvd; + iEta = uRemaining / iAvgSpeed; + } + } + } + + if(uTotal > 0) + { + double dPerc = (double)(((double)uRecvd) * 100.0) / (double)uTotal; + iW -= 2; + int iL = (int) ((((double)iW) * dPerc) / 100.0); + //iR = iW - iL; + p->fillRect(rect.left() + 5, rect.top() + 5,iL,10,bIsTerminated ? QColor(140,110,110) : QColor(200,100,100)); + + txt = QString(__tr2qs_ctx("%1 of %2 (%3 %)","http")).arg(KviQString::makeSizeReadable(uRecvd), + KviQString::makeSizeReadable(uTotal)).arg(dPerc,0,'f',2); + } else { + txt = KviQString::makeSizeReadable(m_pHttpRequest->receivedSize()); + } + + p->setPen(Qt::black); + + p->drawText(rect.left() + 4, rect.top() + 19,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,txt); + + int iLeftHalf = (iW - 2) / 2; + int iRightHalf = iW - (iLeftHalf + 1); + int iLineSpacing = fm.lineSpacing() + 2; + /* + txt = __tr2qs_ctx("Spd:","dcc"); + txt += " "; + if(iInstantSpeed >= 0) + { + QString tmpisp; + KviNetUtils::formatNetworkBandwidthString(tmpisp,iAvgSpeed); + txt += tmpisp; + } else { + txt += "? B/s"; + } + */ + txt = __tr2qs_ctx("Avg:","dcc"); + txt += " "; + if(iAvgSpeed >= 0) + { + QString tmpspd; + KviNetUtils::formatNetworkBandwidthString(tmpspd,iAvgSpeed); + txt += tmpspd; + } else { + txt += "? B/s"; + } + + + + int iDaH = height - (iLineSpacing + 4); + + p->setPen(QColor(180,180,200)); + p->drawRect(rect.left() + 4, rect.top() + iDaH,iLeftHalf,iLineSpacing); + p->fillRect(rect.left() + 5, rect.top() + iDaH + 1,iLeftHalf - 2,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240)); + p->setPen(bIsTerminated ? Qt::darkGray : Qt::black); + p->drawText(rect.left() + 6, rect.top() + iDaH,iLeftHalf - 4,iLineSpacing,Qt::AlignLeft | Qt::AlignVCenter,txt); + + unsigned int uD,uH,uM,uS; + + if(bIsTerminated) + { + KviTimeUtils::secondsToDaysHoursMinsSecs(kvi_timeSpan(m_tTransferEndTime,m_tTransferStartTime),&uD,&uH,&uM,&uS); + txt = "TOT: "; + if(uD > 0)txt += __tr2qs_ctx("%1d %2h %3m %4s","http").arg(uD).arg(uH).arg(uM).arg(uS); + else if(uH > 0)txt += __tr2qs_ctx("%1h %2m %3s","http").arg(uH).arg(uM).arg(uS); + else txt += __tr2qs_ctx("%1m %2s","http").arg(uM).arg(uS); + } else { + if(iEta >= 0) + { + KviTimeUtils::secondsToDaysHoursMinsSecs(iEta,&uD,&uH,&uM,&uS); + txt = "ETA: "; + if(uD > 0)txt += __tr2qs_ctx("%1d %2h %3m %4s","http").arg(uD).arg(uH).arg(uM).arg(uS); + else if(uH > 0)txt += __tr2qs_ctx("%1h %2m %3s","http").arg(uH).arg(uM).arg(uS); + else txt += __tr2qs_ctx("%1m %2s","http").arg(uM).arg(uS); + } else { + txt = "ETA: Unknown"; + } + } + + p->setPen(QColor(180,180,200)); + p->drawRect(rect.left() + width - (4 + iRightHalf), rect.top() + iDaH,iRightHalf,iLineSpacing); + p->fillRect(rect.left() + width - (3 + iRightHalf), rect.top() + iDaH + 1,iRightHalf - 2,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240)); + p->setPen(bIsTerminated ? Qt::darkGray : Qt::black); + p->drawText(rect.left() + width - (2 + iRightHalf), rect.top() + iDaH,iRightHalf - 4,iLineSpacing,Qt::AlignLeft | Qt::AlignVCenter,txt); + + } + break; + } +} + +int HttpFileTransfer::displayHeight(int iLineSpacing) +{ + int iH = (iLineSpacing * 3) + 10; + return iH >= 70 ? iH : 70; +} + +QString HttpFileTransfer::tipText() +{ + QString s; + s = QString("
").arg(id()); + + if(m_lRequest.count() > 0) + { + s += ""; + s += ""; + } + + if(m_lHeaders.count() > 0) + { + s += ""; + s += ""; + } + + s += "
HTTP Transfer (ID %1)
Request Headers
"; + for(QStringList::ConstIterator it = m_lRequest.begin();it != m_lRequest.end();++it) + { + s += "   "; + s += *it; + s += "
"; + } + s += "
Response Headers
"; + for(QStringList::ConstIterator it = m_lHeaders.begin();it != m_lHeaders.end();++it) + { + s += "   "; + s += *it; + s += "
"; + } + s += "
"; + + return s; +} + +void HttpFileTransfer::init() +{ + if(g_pHttpFileTransfers)return; + g_pHttpFileTransfers = new KviPointerList; + g_pHttpFileTransfers->setAutoDelete(false); + + QPixmap * pix = g_pIconManager->getImage("kvi_httpicons.png", false); + if(pix) + g_pHttpIcon = new QPixmap(*pix); + else + g_pHttpIcon = 0; +} + +void HttpFileTransfer::done() +{ + if(!g_pHttpFileTransfers)return; + while(HttpFileTransfer * t = g_pHttpFileTransfers->first()) + delete t; + delete g_pHttpFileTransfers; + g_pHttpFileTransfers = 0; + if(g_pHttpIcon) + { + delete g_pHttpIcon; + g_pHttpIcon = 0; + } +} + +unsigned int HttpFileTransfer::runningTransfers() +{ + if(!g_pHttpFileTransfers)return 0; + return g_pHttpFileTransfers->count(); +} + +void HttpFileTransfer::requestSent(const QStringList &requestHeaders) +{ + m_szStatusString = __tr2qs_ctx("Request sent, waiting for reply...","http"); + displayUpdate(); + + KviWindow * out = transferWindow(); + if(!out)return; + + if(!m_bNoOutput) + out->output(KVI_OUT_GENERICSTATUS,__tr2qs_ctx("[HTTP %d]: Request data sent:","http"),id()); + + for(QStringList::ConstIterator it = requestHeaders.begin();it != requestHeaders.end();++it) + { + if(!m_bNoOutput) + out->output(KVI_OUT_GENERICSTATUS,"[HTTP %d]: %s",id(),(*it).toUtf8().data()); + } + + m_lRequest = requestHeaders; +} + +void HttpFileTransfer::connectionEstabilished() +{ + m_szStatusString = __tr2qs_ctx("Connection established, sending request","http"); + displayUpdate(); +} + +void HttpFileTransfer::resolvingHost(const QString &hostname) +{ + m_szStatusString = __tr2qs_ctx("Resolving host %1","http").arg(hostname); + displayUpdate(); +} + +void HttpFileTransfer::contactingHost(const QString &ipandport) +{ + m_szStatusString = __tr2qs_ctx("Contacting host %1","http").arg(ipandport); + displayUpdate(); +} + +void HttpFileTransfer::receivedResponse(const QString &response) +{ + m_lHeaders.clear(); + m_lHeaders.append(response); + m_szStatusString = __tr2qs_ctx("Transferring data (%1)","http").arg(response); + m_tTransferStartTime = kvi_unixTime(); + m_eGeneralStatus = Downloading; + displayUpdate(); +} + +void HttpFileTransfer::statusMessage(const QString &txt) +{ + KviWindow * out = transferWindow(); + if(out && (!m_bNoOutput)) + out->output(KVI_OUT_GENERICSTATUS,"[HTTP %d]: %Q",id(),&txt); +} + +void HttpFileTransfer::transferTerminated(bool bSuccess) +{ + KviWindow * out = transferWindow(); + + m_tTransferEndTime = kvi_unixTime(); + + KviKvsVariantList vParams; + vParams.append(bSuccess); + vParams.append(new KviKvsVariant(m_pHttpRequest->url().url(), true)); + vParams.append(new KviKvsVariant(m_pHttpRequest->fileName(), true)); + vParams.append(new KviKvsVariant(m_vMagicIdentifier)); + + if(m_szCompletionCallback.isNull()) + { + KVS_TRIGGER_EVENT(KviEvent_OnHTTPGetTerminated,out ? out : (KviWindow *)(g_pApp->activeConsole()),&vParams) + } else { + KviKvsScript::run(m_szCompletionCallback,out ? out : (KviWindow *)(g_pApp->activeConsole()),&vParams); + } + + if(bSuccess) + { + m_szStatusString = __tr2qs_ctx("Transfer completed","http"); + m_eGeneralStatus = Success; + displayUpdate(); + if(out && (!m_bNoOutput))out->output(KVI_OUT_GENERICSUCCESS,__tr2qs_ctx("[HTTP %d]: Transfer completed","http"),id()); + g_pApp->fileDownloadTerminated(true,m_pHttpRequest->url().url(),m_pHttpRequest->fileName(),QString(),QString(),!m_bNotifyCompletion); + } else { + m_szStatusString = __tr2qs_ctx("Transfer failed","http"); + m_szStatusString += ": "; + m_szStatusString += m_pHttpRequest->lastError(); + m_eGeneralStatus = Failure; + displayUpdate(); + if(out && (!m_bNoOutput))out->output(KVI_OUT_GENERICERROR,__tr2qs_ctx("[HTTP %d]: Transfer failed: %Q","http"),id(),&(m_pHttpRequest->lastError())); + g_pApp->fileDownloadTerminated(false,m_pHttpRequest->url().url(),m_pHttpRequest->fileName(),QString(),m_pHttpRequest->lastError(),!m_bNotifyCompletion); + } + + if(m_bAutoClean) + { + if(m_pAutoCleanTimer)delete m_pAutoCleanTimer; + m_pAutoCleanTimer = new QTimer(); + connect(m_pAutoCleanTimer,SIGNAL(timeout()),this,SLOT(autoClean())); + m_pAutoCleanTimer->start(100); + m_TimerId=m_pAutoCleanTimer->timerId(); + } +} + +void HttpFileTransfer::headersReceived(KviPointerHashTable *h) +{ + if(!h)return; + KviWindow * out = transferWindow(); + + if(out && (!m_bNoOutput))out->output(KVI_OUT_GENERICSTATUS,__tr2qs_ctx("[HTTP %d]: Response headers:","http"),id()); + KviPointerHashTableIterator it(*h); + while(KviCString * s = it.current()) + { + QString szHeader = it.currentKey(); + szHeader += ": "; + szHeader += s->ptr(); + m_lHeaders.append(szHeader); + if(out && (!m_bNoOutput))out->output(KVI_OUT_GENERICSTATUS,"[HTTP %d]: %s: %s",id(),it.currentKey(),s->ptr()); + ++it; + } +} + +bool HttpFileTransfer::startDownload() +{ + m_eGeneralStatus = Connecting; + return m_pHttpRequest->start(); +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_HttpFileTransfer.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/http/HttpFileTransfer.h b/src/modules/http/HttpFileTransfer.h new file mode 100644 index 000000000..b89c465b9 --- /dev/null +++ b/src/modules/http/HttpFileTransfer.h @@ -0,0 +1,99 @@ +#ifndef _HTTPFILETRANSFER_H_ +#define _HTTPFILETRANSFER_H_ +//============================================================================= +// +// File : HttpFileTransfer.h +// Creation date : Tue Apr 22 2003 02:00:12 GMT by Szymon Stefanek +// +// This config is part of the KVIrc irc client distribution +// Copyright (C) 2003-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviFileTransfer.h" +#include "KviHttpRequest.h" +#include "KviTimeUtils.h" +#include "KviKvsVariant.h" + +#include +#include + +class QPainter; +class KviTalPopupMenu; + +class HttpFileTransfer : public KviFileTransfer +{ + enum GeneralStatus { Initializing, Connecting, Downloading, Success, Failure }; + Q_OBJECT +public: + HttpFileTransfer(); + ~HttpFileTransfer(); +private: + int m_TimerId; + KviHttpRequest * m_pHttpRequest; + GeneralStatus m_eGeneralStatus; + QString m_szStatusString; + + QStringList m_lHeaders; + QStringList m_lRequest; + + kvi_time_t m_tStartTime; + kvi_time_t m_tTransferStartTime; + kvi_time_t m_tTransferEndTime; + + KviKvsVariant m_vMagicIdentifier; + bool m_bNotifyCompletion; + bool m_bAutoClean; + bool m_bNoOutput; + + QTimer * m_pAutoCleanTimer; + QString m_szCompletionCallback; +public: + KviHttpRequest * request(){ return m_pHttpRequest; }; + static unsigned int runningTransfers(); + static void init(); + static void done(); + + virtual bool startDownload(); + + void setCompletionCallback(const QString &szCallback){ m_szCompletionCallback = szCallback; }; + void setMagicIdentifier(const KviKvsVariant &vIdentifier){ m_vMagicIdentifier = vIdentifier; }; + void setNotifyCompletion(bool bNotify){ m_bNotifyCompletion = bNotify; }; + void setAutoClean(bool bAutoClean){ m_bAutoClean = bAutoClean; }; + void setNoOutput(bool bNoOutput){ m_bNoOutput = bNoOutput; }; + + virtual void displayPaint(QPainter * p,int column, QRect rect); + virtual int displayHeight(int iLineSpacing); + virtual void fillContextPopup(KviTalPopupMenu * m); + virtual bool active(); + virtual QString tipText(); + virtual QString localFileName(); +protected slots: + void statusMessage(const QString &txt); + void transferTerminated(bool bSuccess); + void headersReceived(KviPointerHashTable *h); + void requestSent(const QStringList &sl); + + void resolvingHost(const QString &hostname); + void contactingHost(const QString &ipandport); + void receivedResponse(const QString &response); + void connectionEstabilished(); + void abort(); + void autoClean(); +}; + +#endif //!_HTTPFILETRANSFER_H_ diff --git a/src/modules/http/httpfiletransfer.cpp b/src/modules/http/httpfiletransfer.cpp deleted file mode 100644 index 2c48b49c2..000000000 --- a/src/modules/http/httpfiletransfer.cpp +++ /dev/null @@ -1,493 +0,0 @@ -//============================================================================= -// -// File : httpfiletransfer.h -// Creation date : Tue Apr 22 2003 02:00:12 GMT by Szymon Stefanek -// -// This config is part of the KVIrc irc client distribution -// Copyright (C) 2003-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "httpfiletransfer.h" - -#include "KviApplication.h" -#include "kvi_out.h" -#include "KviLocale.h" -#include "KviWindow.h" -#include "KviIconManager.h" -#include "KviNetUtils.h" -#include "KviKvsEventTriggers.h" -#include "KviConsoleWindow.h" -#include "KviKvsScript.h" -#include "KviTalPopupMenu.h" - -#include - -static KviPointerList * g_pHttpFileTransfers = 0; -static QPixmap * g_pHttpIcon = 0; - - -KviHttpFileTransfer::KviHttpFileTransfer() -: KviFileTransfer() -{ - init(); // ensure we're initialized - g_pHttpFileTransfers->append(this); - - m_tStartTime = kvi_unixTime(); - m_tTransferStartTime = 0; - m_tTransferEndTime = 0; - - m_bNotifyCompletion = true; - m_bAutoClean = false; - m_pAutoCleanTimer = 0; - m_bNoOutput = false; - - m_pHttpRequest = new KviHttpRequest(); - - connect(m_pHttpRequest,SIGNAL(status(const QString &)),this,SLOT(statusMessage(const QString &))); - connect(m_pHttpRequest,SIGNAL(terminated(bool)),this,SLOT(transferTerminated(bool))); - connect(m_pHttpRequest,SIGNAL(header(KviPointerHashTable *)),this,SLOT(headersReceived(KviPointerHashTable *))); - connect(m_pHttpRequest,SIGNAL(resolvingHost(const QString &)),this,SLOT(resolvingHost(const QString &))); - connect(m_pHttpRequest,SIGNAL(requestSent(const QStringList &)),this,SLOT(requestSent(const QStringList &))); - connect(m_pHttpRequest,SIGNAL(contactingHost(const QString &)),this,SLOT(contactingHost(const QString &))); - connect(m_pHttpRequest,SIGNAL(receivedResponse(const QString &)),this,SLOT(receivedResponse(const QString &))); - connect(m_pHttpRequest,SIGNAL(connectionEstabilished()),this,SLOT(connectionEstabilished())); - - m_eGeneralStatus = Initializing; - m_szStatusString = __tr2qs_ctx("Initializing","http"); -} - -KviHttpFileTransfer::~KviHttpFileTransfer() -{ - g_pHttpFileTransfers->removeRef(this); - delete m_pHttpRequest; - if(m_pAutoCleanTimer) - { - m_pAutoCleanTimer->stop(); - delete m_pAutoCleanTimer; - } -} - -void KviHttpFileTransfer::autoClean() -{ - killTimer(m_TimerId); - die(); -} - -QString KviHttpFileTransfer::localFileName() -{ - return m_pHttpRequest->fileName(); -} - -void KviHttpFileTransfer::abort() -{ - m_pHttpRequest->abort(); -} - -void KviHttpFileTransfer::fillContextPopup(KviTalPopupMenu * m) -{ - int id = m->insertItem(__tr2qs_ctx("Abort","http"),this,SLOT(abort())); - if(!active())m->setItemEnabled(id,false); -} - -bool KviHttpFileTransfer::active() -{ - return ((m_eGeneralStatus == Connecting) || (m_eGeneralStatus == Downloading)); -} - -void KviHttpFileTransfer::displayPaint(QPainter * p,int column, QRect rect) -{ - int width = rect.width(), height = rect.height(); - QString txt; - bool bIsTerminated = ((m_eGeneralStatus == Success) || (m_eGeneralStatus == Failure)); - - switch(column) - { - case COLUMN_TRANSFERTYPE: - { - int offset = 0; - switch(m_eGeneralStatus) - { - case Initializing: - case Connecting: offset = 0; break; - case Downloading: offset = 48; break; - case Success: offset = 96; break; - case Failure: offset = 144; break; - } - if(g_pHttpIcon) - p->drawPixmap(rect.left() + 3, rect.top() + 3,*g_pHttpIcon,offset,0,48,64); - } - break; - case COLUMN_FILEINFO: - { - QFontMetrics fm(p->font()); - - QString szFrom = __tr2qs_ctx("From: ","http"); - QString szTo = __tr2qs_ctx("To: ","http"); - - int daW1 = fm.width(szFrom); - int daW2 = fm.width(szTo); - if(daW1 < daW2)daW1 = daW2; - int iLineSpacing = fm.lineSpacing(); - - p->setPen(Qt::black); - - int iY = rect.top() + 4; - - p->drawText(rect.left() + 4 + daW1,iY,width - (8 + daW1),height - 8,Qt::AlignTop | Qt::AlignLeft,m_pHttpRequest->url().url()); - iY += iLineSpacing; - if(!(m_pHttpRequest->fileName().isEmpty())) - { - p->drawText(rect.left() + 4 + daW1,iY,width - (8 + daW1),height - 8,Qt::AlignTop | Qt::AlignLeft,m_pHttpRequest->fileName()); - } - iY += iLineSpacing; - - - p->setPen(Qt::darkGray); - - p->drawText(rect.left() + 4, rect.top() + 4,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,szFrom); - p->drawText(rect.left() + 4, rect.top() + 4 + iLineSpacing,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,szTo); - - p->setPen(QColor(180,180,200)); - - iLineSpacing += 2; - - p->drawRect(rect.left() + 4, rect.top() + height - (iLineSpacing + 4),width - 8,iLineSpacing); - p->fillRect(rect.left() + 5, rect.top() + height - (iLineSpacing + 3),width - 10,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240)); - p->setPen(Qt::black); - p->drawText(rect.left() + 7, rect.top() + height - (iLineSpacing + 4),width - 14,iLineSpacing,Qt::AlignVCenter | Qt::AlignLeft,m_szStatusString); - } - break; - case COLUMN_PROGRESS: - { - QFontMetrics fm(p->font()); - - unsigned int uTotal = m_pHttpRequest->totalSize(); - unsigned int uRecvd = m_pHttpRequest->receivedSize(); - int iW = width - 8; - - p->setPen(bIsTerminated ? Qt::lightGray : QColor(210,210,240)); - p->drawRect(rect.left() + 4, rect.top() + 4,iW,12); - - int iAvgSpeed = -1; - int iEta = -1; - - if(m_tTransferStartTime > 0) - { - int tSpan = kvi_timeSpan(m_tTransferEndTime > 0 ? m_tTransferEndTime : kvi_unixTime(),m_tTransferStartTime); - if(tSpan > 0) - { - //qDebug("SPAN: %d (%d - %d)",tSpan,m_tTransferEndTime > 0 ? m_tTransferEndTime : kvi_unixTime(),m_tTransferStartTime); - iAvgSpeed = uRecvd / tSpan; - if(!bIsTerminated && (uTotal >= uRecvd)) - { - unsigned int uRemaining = uTotal - uRecvd; - iEta = uRemaining / iAvgSpeed; - } - } - } - - if(uTotal > 0) - { - double dPerc = (double)(((double)uRecvd) * 100.0) / (double)uTotal; - iW -= 2; - int iL = (int) ((((double)iW) * dPerc) / 100.0); - //iR = iW - iL; - p->fillRect(rect.left() + 5, rect.top() + 5,iL,10,bIsTerminated ? QColor(140,110,110) : QColor(200,100,100)); - - txt = QString(__tr2qs_ctx("%1 of %2 (%3 %)","http")).arg(KviQString::makeSizeReadable(uRecvd), - KviQString::makeSizeReadable(uTotal)).arg(dPerc,0,'f',2); - } else { - txt = KviQString::makeSizeReadable(m_pHttpRequest->receivedSize()); - } - - p->setPen(Qt::black); - - p->drawText(rect.left() + 4, rect.top() + 19,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,txt); - - int iLeftHalf = (iW - 2) / 2; - int iRightHalf = iW - (iLeftHalf + 1); - int iLineSpacing = fm.lineSpacing() + 2; - /* - txt = __tr2qs_ctx("Spd:","dcc"); - txt += " "; - if(iInstantSpeed >= 0) - { - QString tmpisp; - KviNetUtils::formatNetworkBandwidthString(tmpisp,iAvgSpeed); - txt += tmpisp; - } else { - txt += "? B/s"; - } - */ - txt = __tr2qs_ctx("Avg:","dcc"); - txt += " "; - if(iAvgSpeed >= 0) - { - QString tmpspd; - KviNetUtils::formatNetworkBandwidthString(tmpspd,iAvgSpeed); - txt += tmpspd; - } else { - txt += "? B/s"; - } - - - - int iDaH = height - (iLineSpacing + 4); - - p->setPen(QColor(180,180,200)); - p->drawRect(rect.left() + 4, rect.top() + iDaH,iLeftHalf,iLineSpacing); - p->fillRect(rect.left() + 5, rect.top() + iDaH + 1,iLeftHalf - 2,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240)); - p->setPen(bIsTerminated ? Qt::darkGray : Qt::black); - p->drawText(rect.left() + 6, rect.top() + iDaH,iLeftHalf - 4,iLineSpacing,Qt::AlignLeft | Qt::AlignVCenter,txt); - - unsigned int uD,uH,uM,uS; - - if(bIsTerminated) - { - KviTimeUtils::secondsToDaysHoursMinsSecs(kvi_timeSpan(m_tTransferEndTime,m_tTransferStartTime),&uD,&uH,&uM,&uS); - txt = "TOT: "; - if(uD > 0)txt += __tr2qs_ctx("%1d %2h %3m %4s","http").arg(uD).arg(uH).arg(uM).arg(uS); - else if(uH > 0)txt += __tr2qs_ctx("%1h %2m %3s","http").arg(uH).arg(uM).arg(uS); - else txt += __tr2qs_ctx("%1m %2s","http").arg(uM).arg(uS); - } else { - if(iEta >= 0) - { - KviTimeUtils::secondsToDaysHoursMinsSecs(iEta,&uD,&uH,&uM,&uS); - txt = "ETA: "; - if(uD > 0)txt += __tr2qs_ctx("%1d %2h %3m %4s","http").arg(uD).arg(uH).arg(uM).arg(uS); - else if(uH > 0)txt += __tr2qs_ctx("%1h %2m %3s","http").arg(uH).arg(uM).arg(uS); - else txt += __tr2qs_ctx("%1m %2s","http").arg(uM).arg(uS); - } else { - txt = "ETA: Unknown"; - } - } - - p->setPen(QColor(180,180,200)); - p->drawRect(rect.left() + width - (4 + iRightHalf), rect.top() + iDaH,iRightHalf,iLineSpacing); - p->fillRect(rect.left() + width - (3 + iRightHalf), rect.top() + iDaH + 1,iRightHalf - 2,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240)); - p->setPen(bIsTerminated ? Qt::darkGray : Qt::black); - p->drawText(rect.left() + width - (2 + iRightHalf), rect.top() + iDaH,iRightHalf - 4,iLineSpacing,Qt::AlignLeft | Qt::AlignVCenter,txt); - - } - break; - } -} - -int KviHttpFileTransfer::displayHeight(int iLineSpacing) -{ - int iH = (iLineSpacing * 3) + 10; - return iH >= 70 ? iH : 70; -} - -QString KviHttpFileTransfer::tipText() -{ - QString s; - s = QString("
").arg(id()); - - if(m_lRequest.count() > 0) - { - s += ""; - s += ""; - } - - if(m_lHeaders.count() > 0) - { - s += ""; - s += ""; - } - - s += "
HTTP Transfer (ID %1)
Request Headers
"; - for(QStringList::ConstIterator it = m_lRequest.begin();it != m_lRequest.end();++it) - { - s += "   "; - s += *it; - s += "
"; - } - s += "
Response Headers
"; - for(QStringList::ConstIterator it = m_lHeaders.begin();it != m_lHeaders.end();++it) - { - s += "   "; - s += *it; - s += "
"; - } - s += "
"; - - return s; -} - -void KviHttpFileTransfer::init() -{ - if(g_pHttpFileTransfers)return; - g_pHttpFileTransfers = new KviPointerList; - g_pHttpFileTransfers->setAutoDelete(false); - - QPixmap * pix = g_pIconManager->getImage("kvi_httpicons.png", false); - if(pix) - g_pHttpIcon = new QPixmap(*pix); - else - g_pHttpIcon = 0; -} - -void KviHttpFileTransfer::done() -{ - if(!g_pHttpFileTransfers)return; - while(KviHttpFileTransfer * t = g_pHttpFileTransfers->first()) - delete t; - delete g_pHttpFileTransfers; - g_pHttpFileTransfers = 0; - if(g_pHttpIcon) - { - delete g_pHttpIcon; - g_pHttpIcon = 0; - } -} - -unsigned int KviHttpFileTransfer::runningTransfers() -{ - if(!g_pHttpFileTransfers)return 0; - return g_pHttpFileTransfers->count(); -} - -void KviHttpFileTransfer::requestSent(const QStringList &requestHeaders) -{ - m_szStatusString = __tr2qs_ctx("Request sent, waiting for reply...","http"); - displayUpdate(); - - KviWindow * out = transferWindow(); - if(!out)return; - - if(!m_bNoOutput) - out->output(KVI_OUT_GENERICSTATUS,__tr2qs_ctx("[HTTP %d]: Request data sent:","http"),id()); - - for(QStringList::ConstIterator it = requestHeaders.begin();it != requestHeaders.end();++it) - { - if(!m_bNoOutput) - out->output(KVI_OUT_GENERICSTATUS,"[HTTP %d]: %s",id(),(*it).toUtf8().data()); - } - - m_lRequest = requestHeaders; -} - -void KviHttpFileTransfer::connectionEstabilished() -{ - m_szStatusString = __tr2qs_ctx("Connection established, sending request","http"); - displayUpdate(); -} - -void KviHttpFileTransfer::resolvingHost(const QString &hostname) -{ - m_szStatusString = __tr2qs_ctx("Resolving host %1","http").arg(hostname); - displayUpdate(); -} - -void KviHttpFileTransfer::contactingHost(const QString &ipandport) -{ - m_szStatusString = __tr2qs_ctx("Contacting host %1","http").arg(ipandport); - displayUpdate(); -} - -void KviHttpFileTransfer::receivedResponse(const QString &response) -{ - m_lHeaders.clear(); - m_lHeaders.append(response); - m_szStatusString = __tr2qs_ctx("Transferring data (%1)","http").arg(response); - m_tTransferStartTime = kvi_unixTime(); - m_eGeneralStatus = Downloading; - displayUpdate(); -} - -void KviHttpFileTransfer::statusMessage(const QString &txt) -{ - KviWindow * out = transferWindow(); - if(out && (!m_bNoOutput)) - out->output(KVI_OUT_GENERICSTATUS,"[HTTP %d]: %Q",id(),&txt); -} - -void KviHttpFileTransfer::transferTerminated(bool bSuccess) -{ - KviWindow * out = transferWindow(); - - m_tTransferEndTime = kvi_unixTime(); - - KviKvsVariantList vParams; - vParams.append(bSuccess); - vParams.append(new KviKvsVariant(m_pHttpRequest->url().url(), true)); - vParams.append(new KviKvsVariant(m_pHttpRequest->fileName(), true)); - vParams.append(new KviKvsVariant(m_vMagicIdentifier)); - - if(m_szCompletionCallback.isNull()) - { - KVS_TRIGGER_EVENT(KviEvent_OnHTTPGetTerminated,out ? out : (KviWindow *)(g_pApp->activeConsole()),&vParams) - } else { - KviKvsScript::run(m_szCompletionCallback,out ? out : (KviWindow *)(g_pApp->activeConsole()),&vParams); - } - - if(bSuccess) - { - m_szStatusString = __tr2qs_ctx("Transfer completed","http"); - m_eGeneralStatus = Success; - displayUpdate(); - if(out && (!m_bNoOutput))out->output(KVI_OUT_GENERICSUCCESS,__tr2qs_ctx("[HTTP %d]: Transfer completed","http"),id()); - g_pApp->fileDownloadTerminated(true,m_pHttpRequest->url().url(),m_pHttpRequest->fileName(),QString(),QString(),!m_bNotifyCompletion); - } else { - m_szStatusString = __tr2qs_ctx("Transfer failed","http"); - m_szStatusString += ": "; - m_szStatusString += m_pHttpRequest->lastError(); - m_eGeneralStatus = Failure; - displayUpdate(); - if(out && (!m_bNoOutput))out->output(KVI_OUT_GENERICERROR,__tr2qs_ctx("[HTTP %d]: Transfer failed: %Q","http"),id(),&(m_pHttpRequest->lastError())); - g_pApp->fileDownloadTerminated(false,m_pHttpRequest->url().url(),m_pHttpRequest->fileName(),QString(),m_pHttpRequest->lastError(),!m_bNotifyCompletion); - } - - if(m_bAutoClean) - { - if(m_pAutoCleanTimer)delete m_pAutoCleanTimer; - m_pAutoCleanTimer = new QTimer(); - connect(m_pAutoCleanTimer,SIGNAL(timeout()),this,SLOT(autoClean())); - m_pAutoCleanTimer->start(100); - m_TimerId=m_pAutoCleanTimer->timerId(); - } -} - -void KviHttpFileTransfer::headersReceived(KviPointerHashTable *h) -{ - if(!h)return; - KviWindow * out = transferWindow(); - - if(out && (!m_bNoOutput))out->output(KVI_OUT_GENERICSTATUS,__tr2qs_ctx("[HTTP %d]: Response headers:","http"),id()); - KviPointerHashTableIterator it(*h); - while(KviCString * s = it.current()) - { - QString szHeader = it.currentKey(); - szHeader += ": "; - szHeader += s->ptr(); - m_lHeaders.append(szHeader); - if(out && (!m_bNoOutput))out->output(KVI_OUT_GENERICSTATUS,"[HTTP %d]: %s: %s",id(),it.currentKey(),s->ptr()); - ++it; - } -} - -bool KviHttpFileTransfer::startDownload() -{ - m_eGeneralStatus = Connecting; - return m_pHttpRequest->start(); -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_httpfiletransfer.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/http/httpfiletransfer.h b/src/modules/http/httpfiletransfer.h deleted file mode 100644 index 6369087e2..000000000 --- a/src/modules/http/httpfiletransfer.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef _HTTPFILETRANSFER_H_ -#define _HTTPFILETRANSFER_H_ -//============================================================================= -// -// File : httpfiletransfer.h -// Creation date : Tue Apr 22 2003 02:00:12 GMT by Szymon Stefanek -// -// This config is part of the KVIrc irc client distribution -// Copyright (C) 2003-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "KviFileTransfer.h" -#include "KviHttpRequest.h" -#include "KviTimeUtils.h" -#include "KviKvsVariant.h" - -#include -#include - -class QPainter; -class KviTalPopupMenu; - -class KviHttpFileTransfer : public KviFileTransfer -{ - enum GeneralStatus { Initializing, Connecting, Downloading, Success, Failure }; - Q_OBJECT -public: - KviHttpFileTransfer(); - ~KviHttpFileTransfer(); -private: - int m_TimerId; - KviHttpRequest * m_pHttpRequest; - GeneralStatus m_eGeneralStatus; - QString m_szStatusString; - - QStringList m_lHeaders; - QStringList m_lRequest; - - kvi_time_t m_tStartTime; - kvi_time_t m_tTransferStartTime; - kvi_time_t m_tTransferEndTime; - - KviKvsVariant m_vMagicIdentifier; - bool m_bNotifyCompletion; - bool m_bAutoClean; - bool m_bNoOutput; - - QTimer * m_pAutoCleanTimer; - QString m_szCompletionCallback; -public: - KviHttpRequest * request(){ return m_pHttpRequest; }; - static unsigned int runningTransfers(); - static void init(); - static void done(); - - virtual bool startDownload(); - - void setCompletionCallback(const QString &szCallback){ m_szCompletionCallback = szCallback; }; - void setMagicIdentifier(const KviKvsVariant &vIdentifier){ m_vMagicIdentifier = vIdentifier; }; - void setNotifyCompletion(bool bNotify){ m_bNotifyCompletion = bNotify; }; - void setAutoClean(bool bAutoClean){ m_bAutoClean = bAutoClean; }; - void setNoOutput(bool bNoOutput){ m_bNoOutput = bNoOutput; }; - - virtual void displayPaint(QPainter * p,int column, QRect rect); - virtual int displayHeight(int iLineSpacing); - virtual void fillContextPopup(KviTalPopupMenu * m); - virtual bool active(); - virtual QString tipText(); - virtual QString localFileName(); -protected slots: - void statusMessage(const QString &txt); - void transferTerminated(bool bSuccess); - void headersReceived(KviPointerHashTable *h); - void requestSent(const QStringList &sl); - - void resolvingHost(const QString &hostname); - void contactingHost(const QString &ipandport); - void receivedResponse(const QString &response); - void connectionEstabilished(); - void abort(); - void autoClean(); -}; - -#endif //!_HTTPFILETRANSFER_H_ diff --git a/src/modules/http/libkvihttp.cpp b/src/modules/http/libkvihttp.cpp index c6ffb1eed..41e096220 100644 --- a/src/modules/http/libkvihttp.cpp +++ b/src/modules/http/libkvihttp.cpp @@ -22,7 +22,7 @@ // //============================================================================= -#include "httpfiletransfer.h" +#include "HttpFileTransfer.h" #include "KviModule.h" #include "KviCString.h" @@ -63,7 +63,7 @@ static bool http_kvs_complete_get(KviKvsModuleCommandCall * c,QString &szUrl,QSt } } - KviHttpFileTransfer * hft = new KviHttpFileTransfer(); + HttpFileTransfer * hft = new HttpFileTransfer(); bool bHead = c->switches()->find('h',"head"); @@ -303,7 +303,7 @@ static bool http_kvs_cmd_asyncGet(KviKvsModuleCallbackCommandCall * c) static bool http_module_init(KviModule * m) { - KviHttpFileTransfer::init(); + HttpFileTransfer::init(); KVSM_REGISTER_SIMPLE_COMMAND(m,"get",http_kvs_cmd_get); KVSM_REGISTER_CALLBACK_COMMAND(m,"asyncGet",http_kvs_cmd_asyncGet); @@ -313,13 +313,13 @@ static bool http_module_init(KviModule * m) static bool http_module_cleanup(KviModule *) { - KviHttpFileTransfer::done(); + HttpFileTransfer::done(); return true; } static bool http_module_can_unload(KviModule *) { - return (KviHttpFileTransfer::runningTransfers() == 0); + return (HttpFileTransfer::runningTransfers() == 0); } KVIRC_MODULE( diff --git a/src/modules/links/CMakeLists.txt b/src/modules/links/CMakeLists.txt index 1ffe5e95d..17299d9f7 100644 --- a/src/modules/links/CMakeLists.txt +++ b/src/modules/links/CMakeLists.txt @@ -1,12 +1,12 @@ # CMakeLists for src/modules/links SET(kvilinks_MOC_HDRS - linkswindow.h + LinksWindow.h ) SET(kvilinks_SRCS libkvilinks.cpp - linkswindow.cpp + LinksWindow.cpp ) # After this call, files will be moc'ed to moc_kvi_*.cpp diff --git a/src/modules/links/LinksWindow.cpp b/src/modules/links/LinksWindow.cpp new file mode 100644 index 000000000..18127b77b --- /dev/null +++ b/src/modules/links/LinksWindow.cpp @@ -0,0 +1,493 @@ +//============================================================================= +// +// File : LinksWindow.cpp +// Creation date : Thu Dec 21 2001 12:41:18 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "LinksWindow.h" + +#include "kvi_debug.h" +#include "KviIconManager.h" +#include "KviIrcView.h" +#include "kvi_out.h" +#include "KviOptions.h" +#include "KviLocale.h" +#include "KviQString.h" +#include "kvi_out.h" +#include "KviMircCntrl.h" +#include "KviThemedLabel.h" +#include "KviIrcContext.h" +#include "KviIrcConnection.h" +#include "KviTalHBox.h" + +#include +#include +#include +#include + +extern KviPointerList * g_pLinksWindowList; + +LinksWindow::LinksWindow(KviMainWindow * lpFrm,KviConsoleWindow * lpConsole) +: KviWindow(KVI_WINDOW_TYPE_LINKS,lpFrm,"links",lpConsole), KviExternalServerDataParser() +{ + g_pLinksWindowList->append(this); + + m_pTopSplitter = new KviTalSplitter(Qt::Horizontal,this); + m_pTopSplitter->setObjectName("top_splitter"); + m_pTopSplitter->setChildrenCollapsible(false); + + // The button box on the left + KviTalHBox * box = new KviTalHBox(m_pTopSplitter); + + m_pRequestButton = new QToolButton(box); + m_pRequestButton->setObjectName("request_button"); + m_pRequestButton->setIconSize(QSize(16,16)); + m_pRequestButton->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_LINKS))); + connect(m_pRequestButton,SIGNAL(clicked()),this,SLOT(requestLinks())); + m_pRequestButton->setToolTip(__tr2qs("Request Links")); + + QLabel * l = new QLabel(box); + box->setStretchFactor(l,1); + m_pInfoLabel = new KviThemedLabel(m_pTopSplitter, this, "info_label"); + + connect(lpConsole->context(),SIGNAL(stateChanged()), + this,SLOT(connectionStateChange())); + + m_pSplitter = new KviTalSplitter(Qt::Horizontal,this); + m_pSplitter->setObjectName("splitter"); + m_pSplitter->setChildrenCollapsible(false); + + m_pVertSplitter = new KviTalSplitter(Qt::Vertical,m_pSplitter); + m_pVertSplitter->setObjectName("vsplitter"); + m_pVertSplitter->setChildrenCollapsible(false); + + m_pListView = new LinksListView(m_pVertSplitter, this, "links_treewidget"); + + connect(m_pListView,SIGNAL(rightButtonPressed(QTreeWidgetItem *,const QPoint &)), + this,SLOT(showHostPopup(QTreeWidgetItem *,const QPoint &))); + + m_pIrcView = new KviIrcView(m_pVertSplitter,lpFrm,this); + + m_pLinkList = new KviPointerList; + m_pLinkList->setAutoDelete(true); + + m_pHostPopup = new KviTalPopupMenu(); + connect(m_pHostPopup,SIGNAL(activated(int)),this,SLOT(hostPopupClicked(int))); + + connectionStateChange(); + + m_pConsole->context()->setLinksWindowPointer(this); + + m_szRootServer = __tr2qs("(None)"); +} + +LinksWindow::~LinksWindow() +{ + g_pLinksWindowList->removeRef(this); + m_pConsole->context()->setLinksWindowPointer(0); + delete m_pLinkList; + delete m_pHostPopup; +} + +void LinksWindow::getBaseLogFileName(QString &buffer) +{ + buffer.sprintf("LINKS_%d",context()->id()); +} + +void LinksWindow::requestLinks() +{ + if(m_pConsole->isConnected()) + { + m_pConsole->connection()->sendFmtData("links"); + outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Sent links request, waiting for reply...")); + m_pRequestButton->setEnabled(false); + } else { + outputNoFmt(KVI_OUT_SYSTEMERROR,__tr2qs("Cannot request links: No active connection")); + } +} + +void LinksWindow::connectionStateChange() +{ + KviIrcContext::State st = m_pConsole->context()->state(); + m_pRequestButton->setEnabled(st == KviIrcContext::Connected); + if(st == KviIrcContext::Connected) + { + QString tmp; + KviQString::sprintf(tmp,__tr2qs("Connected to %s (%s)"),m_pConsole->connection()->currentServerName().toUtf8().data(),m_pConsole->currentNetworkName().toUtf8().data()); + m_pInfoLabel->setText(tmp); + } else { + m_pInfoLabel->setText(__tr2qs("Links cannot be requested: Not connected to a server")); + } +} + +QPixmap * LinksWindow::myIconPtr() +{ + return g_pIconManager->getSmallIcon(KVI_SMALLICON_LINKS); +} + +void LinksWindow::resizeEvent(QResizeEvent *) +{ + int hght2 = m_pTopSplitter->sizeHint().height(); + m_pTopSplitter->setGeometry(0,0,width(),hght2); + m_pSplitter->setGeometry(0,hght2,width(),height() - hght2); +} + +QSize LinksWindow::sizeHint() const +{ + QSize ret(m_pSplitter->sizeHint().width(), + m_pSplitter->sizeHint().height() + m_pTopSplitter->sizeHint().height()); + return ret; +} + +void LinksWindow::fillCaptionBuffers() +{ + KviQString::sprintf(m_szPlainTextCaption,__tr2qs("Links for %Q [IRC Context %u]"),&m_szRootServer,m_pConsole->context()->id()); +} + +void LinksWindow::die() +{ + close(); +} + +void LinksWindow::control(int message) +{ + switch(message) + { + case EXTERNAL_SERVER_DATA_PARSER_CONTROL_RESET: reset(); break; + case EXTERNAL_SERVER_DATA_PARSER_CONTROL_ENDOFDATA: endOfLinks(); break; + } +} + +void LinksWindow::endOfLinks() +{ + m_pRequestButton->setEnabled(true); + + m_pListView->clear(); + //m_pListView->setSorting(-1); + + outputNoFmt(KVI_OUT_SYSTEMMESSAGE,"======================"); + outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Received end of links.")); + outputNoFmt(KVI_OUT_SYSTEMMESSAGE,"======================"); + + QTreeWidgetItem * it = 0; + QTreeWidgetItem * root = 0; + + int totalHosts = 0; + int totalHops = 0; + int maxHops = 0; + int avgHops = 0; + int directLinks = 0; + int nearLinks = 0; + int brokenLinks = 0; + int maxLinks = 0; + int farLinks = 0; + int wildServers = 0; + + KviCString szMaxHop,szMaxLinks; + + m_pListView->setUpdatesEnabled(false); + for(KviLink *l=m_pLinkList->first();l;l=m_pLinkList->next()){ + totalHosts++; + if(l->hops == 0) + { + root = new QTreeWidgetItem(m_pListView); + root->setText(0,QString(l->host.ptr())); + root->setText(1,QString("0")); + root->setText(2,QString(l->description.ptr())); + } else { + totalHops += l->hops; + if(l->hops < 4){ + nearLinks++; + if(l->hops == 1)directLinks++; + } else { + if(l->hops >= 7)farLinks++; + } + if(l->hops == maxHops){ + szMaxHop.append(','); + szMaxHop.append(l->host); + } else if(l->hops > maxHops){ + maxHops = l->hops; + szMaxHop = l->host; + } + if(l->host.contains('*'))wildServers++; + it = insertLink(l); + if(!it) + { + output(KVI_OUT_SYSTEMERROR,__tr2qs("Broken link: Missing parent (%s) for %s (%d hops): %s (used /LINKS ?)"), + l->parent.ptr(),l->host.ptr(),l->hops,l->description.ptr()); + brokenLinks++; + QString tmp; + KviQString::sprintf(tmp,__tr2qs("%s: Parent link %s"),l->description.ptr(),l->parent.ptr()); + KviCString tmp2(KviCString::Format,"%d",l->hops); + if(root) + { + it = new QTreeWidgetItem(root); + it->setText(0,QString(l->host.ptr())); + it->setText(1,QString(tmp2.ptr())); + it->setText(2,tmp); + } else { + outputNoFmt(KVI_OUT_SYSTEMERROR,__tr2qs("Warning: No root link was sent by the server, the stats may be invalid.")); + it = new QTreeWidgetItem(m_pListView); + it->setText(0,QString(l->host.ptr())); + it->setText(1,QString(tmp2.ptr())); + it->setText(2,tmp); + } + } else { + it = (QTreeWidgetItem*) it->parent(); + if(it) + { + int links = it->childCount() + 1; + if(links == maxLinks) + { + szMaxLinks.append(','); + szMaxLinks.append(it->text(0)); + } else if(links > maxLinks) + { + maxLinks = links; + szMaxLinks = it->text(0); + } + } + } + } + } + + avgHops = ((totalHosts > 0) ? ((totalHops * 100) / totalHosts) : 0 ); + int nearProcent = ((totalHosts > 0) ? ((nearLinks * 10000) / totalHosts) : 0); + int directProcent = ((totalHosts > 0) ? ((directLinks * 10000) / totalHosts) : 0); + int midLinks = totalHosts - (farLinks + nearLinks + 1 + brokenLinks); + if(midLinks < 0)midLinks = 0; + int midProcent = ((totalHosts > 0) ? ((midLinks * 10000) / totalHosts) : 0); + int farProcent = ((totalHosts > 0) ? ((farLinks * 10000) / totalHosts) : 0); + + outputNoFmt(KVI_OUT_LINKS,"======================"); + +// if(!root)root = m_pListView->firstChild(); + if(root) + { + m_szRootServer = root->text(0); + output(KVI_OUT_LINKS,__tr2qs("%c%cLinks for %Q"),KviMircCntrl::Bold,KviMircCntrl::Underline,&m_szRootServer); + outputNoFmt(KVI_OUT_LINKS,"======================"); + QString tmpo = wildServers ? __tr2qs("Total hosts listed") : __tr2qs("Total hosts in the network"); + output(KVI_OUT_LINKS,"%Q: %d",&tmpo,totalHosts); + if(wildServers)output(KVI_OUT_LINKS,__tr2qs("Wildcard servers (hubs?): %d"),wildServers); + output(KVI_OUT_LINKS,__tr2qs("Direct links: %d (~%d.%d %)"),directLinks,directProcent / 100, directProcent % 100); + output(KVI_OUT_LINKS,__tr2qs("Close links (1 <= hops <= 3): %d (~%d.%d %)"),nearLinks,nearProcent / 100,nearProcent % 100); + output(KVI_OUT_LINKS,__tr2qs("Mid-range links (4 <= hops <= 6): %d (~%d.%d %)"),midLinks,midProcent / 100,midProcent % 100); + output(KVI_OUT_LINKS,__tr2qs("Distant links (7 <= hops): %d (~%d.%d %)"),farLinks,farProcent / 100,farProcent % 100); + output(KVI_OUT_LINKS,__tr2qs("Broken (unknown) links: %d"),brokenLinks); + output(KVI_OUT_LINKS,__tr2qs("Maximum links per host: %d [%s]"),maxLinks,szMaxLinks.ptr()); + output(KVI_OUT_LINKS,__tr2qs("Total links: %d"),totalHops); + output(KVI_OUT_LINKS,__tr2qs("Maximum hops: %d [%s]"),maxHops,szMaxHop.ptr()); + output(KVI_OUT_LINKS,__tr2qs("Average hops: ~%d.%d"),avgHops / 100,avgHops % 100); + } else { + m_szRootServer = __tr2qs("(Unknown)"); + outputNoFmt(KVI_OUT_LINKS,__tr2qs("Incomplete LINKS result, no stats available")); + } + outputNoFmt(KVI_OUT_LINKS,"======================"); + + updateCaption(); + + + while(!m_pLinkList->isEmpty())m_pLinkList->removeFirst(); + + m_pListView->resizeColumnToContents(0); + m_pListView->setUpdatesEnabled(true); + m_pListView->repaint(); +} + +QTreeWidgetItem * LinksWindow::insertLink(KviLink *l) +{ + KVI_ASSERT(l->hops > 0); + QTreeWidgetItem * i = getItemByHost(l->parent.ptr(),0); + QTreeWidgetItem * it = 0; + if(!i) + { + return 0; + } else { + KviCString hops(KviCString::Format,"%d",l->hops); + it = new QTreeWidgetItem(i); + it->setText(0,QString(l->host.ptr())); + it->setText(1,QString(hops.ptr())); + it->setText(2,QString(l->description.ptr())); + i->setExpanded(true); + } + return it; +} + +QTreeWidgetItem * LinksWindow::getItemByHost(const char *host,QTreeWidgetItem * par) +{ + KviCString tmp; + if(par) + { + for(int i=0;ichildCount();i++) + { + tmp = par->child(i)->text(0); + if(kvi_strEqualCI(tmp.ptr(),host))return par->child(i); + QTreeWidgetItem * ch = getItemByHost(host,par->child(i)); + if(ch)return ch; + } + } else { + for(int i=0;itopLevelItemCount();i++) + { + tmp = m_pListView->topLevelItem(i)->text(0); + if(kvi_strEqualCI(tmp.ptr(),host))return m_pListView->topLevelItem(i); + QTreeWidgetItem * ch = getItemByHost(host,m_pListView->topLevelItem(i)); + if(ch)return ch; + } + } + return 0; +} + +void LinksWindow::showHostPopup(QTreeWidgetItem *i,const QPoint &p) +{ + if(!i)return; + KviCString host=i->text(0); + if(host.isEmpty())return; + m_pHostPopup->clear(); + KviCString tmp(KviCString::Format,"LINKS %s *",host.ptr()); + m_pHostPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_LINKS)),tmp.ptr()); + m_pHostPopup->insertSeparator(); + tmp.sprintf("TIME %s",host.ptr()); + m_pHostPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),tmp.ptr()); + tmp.sprintf("ADMIN %s",host.ptr()); + m_pHostPopup->insertItem(tmp.ptr()); + tmp.sprintf("INFO %s",host.ptr()); + m_pHostPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_SERVERINFO)),tmp.ptr()); + tmp.sprintf("MOTD %s",host.ptr()); + m_pHostPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MOTD)),tmp.ptr()); + tmp.sprintf("VERSION %s",host.ptr()); + m_pHostPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_KVIRC)),tmp.ptr()); + tmp.sprintf("TRACE %s",host.ptr()); + m_pHostPopup->insertItem(tmp.ptr()); + tmp.sprintf("USERS %s",host.ptr()); + m_pHostPopup->insertItem(tmp.ptr()); + m_pHostPopup->insertSeparator(); + tmp.sprintf("STATS c %s",host.ptr()); + m_pHostPopup->insertItem(tmp.ptr()); + tmp.sprintf("STATS d %s",host.ptr()); + m_pHostPopup->insertItem(tmp.ptr()); + tmp.sprintf("STATS h %s",host.ptr()); + m_pHostPopup->insertItem(tmp.ptr()); + tmp.sprintf("STATS i %s",host.ptr()); + m_pHostPopup->insertItem(tmp.ptr()); + tmp.sprintf("STATS k %s",host.ptr()); + m_pHostPopup->insertItem(tmp.ptr()); + tmp.sprintf("STATS l %s",host.ptr()); + m_pHostPopup->insertItem(tmp.ptr()); + tmp.sprintf("STATS m %s",host.ptr()); + m_pHostPopup->insertItem(tmp.ptr()); + tmp.sprintf("STATS o %s",host.ptr()); + m_pHostPopup->insertItem(tmp.ptr()); + tmp.sprintf("STATS t %s",host.ptr()); + m_pHostPopup->insertItem(tmp.ptr()); + tmp.sprintf("STATS u %s",host.ptr()); + m_pHostPopup->insertItem(tmp.ptr()); + tmp.sprintf("STATS y %s",host.ptr()); + m_pHostPopup->insertItem(tmp.ptr()); + tmp.sprintf("STATS z %s",host.ptr()); + m_pHostPopup->insertItem(tmp.ptr()); + m_pHostPopup->popup(p); +} + +void LinksWindow::hostPopupClicked(int id) +{ + KviCString tmp = m_pHostPopup->text(id); + if(tmp.hasData()) + { + if(!connection())output(KVI_OUT_SYSTEMERROR,__tr2qs("You're not connected to a server")); + m_pConsole->connection()->sendData(tmp.ptr()); + } +} + +void LinksWindow::reset() +{ + outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Reset")); + while(!m_pLinkList->isEmpty())m_pLinkList->removeFirst(); +} + +void LinksWindow::processData(KviIrcMessage *msg) +{ + output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Processing link: %s"),msg->allParams()); + KviLink * l = new KviLink; + + l->host = msg->safeParam(1); + l->parent = msg->safeParam(2); + + const char * tr = msg->safeTrailing(); + + if(isdigit(*tr)) + { + const char *aux = tr; + while(*tr && (isdigit(*tr)))tr++; + KviCString tmp(aux,tr - aux); + l->hops = tmp.toInt(); + } else { + outputNoFmt(KVI_OUT_SYSTEMERROR,__tr2qs("Broken message syntax, can't extract hops number, assuming 0")); + l->hops = 0; + } + while(*tr && (*tr == ' '))tr++; + l->description = tr; + uint idx=0; + for(KviLink *m=m_pLinkList->first();m;m=m_pLinkList->next()) + { + if(m->hops >= l->hops) + { + m_pLinkList->insert(idx,l); + return; + } + idx++; + } + m_pLinkList->append(l); +} + +void LinksWindow::applyOptions() +{ + m_pListView->applyOptions(); + m_pInfoLabel->applyOptions(); + m_pIrcView->applyOptions(); + KviWindow::applyOptions(); +} + +LinksListView::LinksListView(QWidget * par, KviWindow * wnd, const char * txt) +: KviThemedTreeWidget(par, wnd, txt) +{ + header()->setSortIndicatorShown(true); + setColumnCount(3); + setHeaderLabels(QStringList() << __tr2qs("Link") << __tr2qs("Hops") << __tr2qs("Description")); + setRootIsDecorated(true); + setAnimated(true); + setSortingEnabled(true); + setAllColumnsShowFocus(true); +} + +void LinksListView::mousePressEvent (QMouseEvent *e) +{ + if (e->button() == Qt::RightButton) + { + QTreeWidgetItem *i=itemAt(e->pos()); + if (i) emit rightButtonPressed(i,QCursor::pos()); + } + KviThemedTreeWidget::mousePressEvent(e); +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_LinksWindow.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/links/LinksWindow.h b/src/modules/links/LinksWindow.h new file mode 100644 index 000000000..807596048 --- /dev/null +++ b/src/modules/links/LinksWindow.h @@ -0,0 +1,99 @@ +#ifndef _LINKSWINDOW_H_ +#define _LINKSWINDOW_H_ +//============================================================================= +// +// File : LinksWindow.h +// Creation date : Thu Dec 21 2000 12:42:55 CEST by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the linkss of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviWindow.h" +#include "KviCString.h" +#include "KviIrcSocket.h" +#include "KviIrcServerParser.h" +#include "KviConsoleWindow.h" +#include "KviIrcContext.h" +#include "KviTalPopupMenu.h" +#include "KviThemedTreeWidget.h" + +#include + +class KviThemedLabel; + +typedef struct _KviLink +{ + KviCString host; + KviCString parent; + int hops; + KviCString description; +} KviLink; + +class LinksListView : public KviThemedTreeWidget +{ + Q_OBJECT +public: + LinksListView(QWidget * par, KviWindow * wnd, const char * txt); + ~LinksListView(){}; +protected: + void mousePressEvent (QMouseEvent *e); +signals: + void rightButtonPressed(QTreeWidgetItem *,QPoint); +}; + +class LinksWindow : public KviWindow, public KviExternalServerDataParser +{ + Q_OBJECT +public: + LinksWindow(KviMainWindow * lpFrm,KviConsoleWindow * lpConsole); + ~LinksWindow(); +protected: + QSplitter * m_pVertSplitter; + QSplitter * m_pTopSplitter; + LinksListView * m_pListView; + KviPointerList * m_pLinkList; + KviTalPopupMenu * m_pHostPopup; + QString m_szRootServer; + QToolButton * m_pRequestButton; + KviThemedLabel * m_pInfoLabel; +public: // Methods + virtual void control(int msg); + virtual void processData(KviIrcMessage * msg); + virtual void die(); +protected: + virtual QPixmap * myIconPtr(); + virtual void fillCaptionBuffers(); + virtual void applyOptions(); + virtual void resizeEvent(QResizeEvent *e); + virtual void getBaseLogFileName(QString &buffer); +protected slots: + void showHostPopup(QTreeWidgetItem *i,const QPoint &p); + void hostPopupClicked(int id); + void requestLinks(); + void connectionStateChange(); +public: + virtual QSize sizeHint() const; +private: + void reset(); + void endOfLinks(); + QTreeWidgetItem * insertLink(KviLink * l); + QTreeWidgetItem * getItemByHost(const char *host,QTreeWidgetItem * par); +}; + +#endif //_KVI_LINKSWINDOW_H_ diff --git a/src/modules/links/libkvilinks.cpp b/src/modules/links/libkvilinks.cpp index 5529e0528..caf5c205d 100644 --- a/src/modules/links/libkvilinks.cpp +++ b/src/modules/links/libkvilinks.cpp @@ -21,7 +21,7 @@ // //============================================================================= -#include "linkswindow.h" +#include "LinksWindow.h" #include "KviModule.h" #include "KviMainWindow.h" @@ -30,7 +30,7 @@ #include -KviPointerList * g_pLinksWindowList = 0; +KviPointerList * g_pLinksWindowList = 0; /* @@ -66,7 +66,7 @@ static bool links_kvs_cmd_open(KviKvsModuleCommandCall * c) if(!(c->window()->context()->linksWindow())) { - KviLinksWindow *w = new KviLinksWindow(c->window()->frame(),c->window()->console()); + LinksWindow *w = new LinksWindow(c->window()->frame(),c->window()->console()); c->window()->frame()->addWindow(w); } else { c->warning(__tr2qs("Links window alread open for this IRC context")); @@ -77,7 +77,7 @@ static bool links_kvs_cmd_open(KviKvsModuleCommandCall * c) static bool links_module_init(KviModule * m) { - g_pLinksWindowList = new KviPointerList; + g_pLinksWindowList = new KviPointerList; g_pLinksWindowList->setAutoDelete(false); diff --git a/src/modules/links/linkswindow.cpp b/src/modules/links/linkswindow.cpp deleted file mode 100644 index 10f68f782..000000000 --- a/src/modules/links/linkswindow.cpp +++ /dev/null @@ -1,493 +0,0 @@ -//============================================================================= -// -// File : linkswindow.cpp -// Creation date : Thu Dec 21 2001 12:41:18 by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "linkswindow.h" - -#include "kvi_debug.h" -#include "KviIconManager.h" -#include "KviIrcView.h" -#include "kvi_out.h" -#include "KviOptions.h" -#include "KviLocale.h" -#include "KviQString.h" -#include "kvi_out.h" -#include "KviMircCntrl.h" -#include "KviThemedLabel.h" -#include "KviIrcContext.h" -#include "KviIrcConnection.h" -#include "KviTalHBox.h" - -#include -#include -#include -#include - -extern KviPointerList * g_pLinksWindowList; - -KviLinksWindow::KviLinksWindow(KviMainWindow * lpFrm,KviConsoleWindow * lpConsole) -: KviWindow(KVI_WINDOW_TYPE_LINKS,lpFrm,"links",lpConsole), KviExternalServerDataParser() -{ - g_pLinksWindowList->append(this); - - m_pTopSplitter = new KviTalSplitter(Qt::Horizontal,this); - m_pTopSplitter->setObjectName("top_splitter"); - m_pTopSplitter->setChildrenCollapsible(false); - - // The button box on the left - KviTalHBox * box = new KviTalHBox(m_pTopSplitter); - - m_pRequestButton = new QToolButton(box); - m_pRequestButton->setObjectName("request_button"); - m_pRequestButton->setIconSize(QSize(16,16)); - m_pRequestButton->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_LINKS))); - connect(m_pRequestButton,SIGNAL(clicked()),this,SLOT(requestLinks())); - m_pRequestButton->setToolTip(__tr2qs("Request Links")); - - QLabel * l = new QLabel(box); - box->setStretchFactor(l,1); - m_pInfoLabel = new KviThemedLabel(m_pTopSplitter, this, "info_label"); - - connect(lpConsole->context(),SIGNAL(stateChanged()), - this,SLOT(connectionStateChange())); - - m_pSplitter = new KviTalSplitter(Qt::Horizontal,this); - m_pSplitter->setObjectName("splitter"); - m_pSplitter->setChildrenCollapsible(false); - - m_pVertSplitter = new KviTalSplitter(Qt::Vertical,m_pSplitter); - m_pVertSplitter->setObjectName("vsplitter"); - m_pVertSplitter->setChildrenCollapsible(false); - - m_pListView = new KviLinksListView(m_pVertSplitter, this, "links_treewidget"); - - connect(m_pListView,SIGNAL(rightButtonPressed(QTreeWidgetItem *,const QPoint &)), - this,SLOT(showHostPopup(QTreeWidgetItem *,const QPoint &))); - - m_pIrcView = new KviIrcView(m_pVertSplitter,lpFrm,this); - - m_pLinkList = new KviPointerList; - m_pLinkList->setAutoDelete(true); - - m_pHostPopup = new KviTalPopupMenu(); - connect(m_pHostPopup,SIGNAL(activated(int)),this,SLOT(hostPopupClicked(int))); - - connectionStateChange(); - - m_pConsole->context()->setLinksWindowPointer(this); - - m_szRootServer = __tr2qs("(None)"); -} - -KviLinksWindow::~KviLinksWindow() -{ - g_pLinksWindowList->removeRef(this); - m_pConsole->context()->setLinksWindowPointer(0); - delete m_pLinkList; - delete m_pHostPopup; -} - -void KviLinksWindow::getBaseLogFileName(QString &buffer) -{ - buffer.sprintf("LINKS_%d",context()->id()); -} - -void KviLinksWindow::requestLinks() -{ - if(m_pConsole->isConnected()) - { - m_pConsole->connection()->sendFmtData("links"); - outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Sent links request, waiting for reply...")); - m_pRequestButton->setEnabled(false); - } else { - outputNoFmt(KVI_OUT_SYSTEMERROR,__tr2qs("Cannot request links: No active connection")); - } -} - -void KviLinksWindow::connectionStateChange() -{ - KviIrcContext::State st = m_pConsole->context()->state(); - m_pRequestButton->setEnabled(st == KviIrcContext::Connected); - if(st == KviIrcContext::Connected) - { - QString tmp; - KviQString::sprintf(tmp,__tr2qs("Connected to %s (%s)"),m_pConsole->connection()->currentServerName().toUtf8().data(),m_pConsole->currentNetworkName().toUtf8().data()); - m_pInfoLabel->setText(tmp); - } else { - m_pInfoLabel->setText(__tr2qs("Links cannot be requested: Not connected to a server")); - } -} - -QPixmap * KviLinksWindow::myIconPtr() -{ - return g_pIconManager->getSmallIcon(KVI_SMALLICON_LINKS); -} - -void KviLinksWindow::resizeEvent(QResizeEvent *) -{ - int hght2 = m_pTopSplitter->sizeHint().height(); - m_pTopSplitter->setGeometry(0,0,width(),hght2); - m_pSplitter->setGeometry(0,hght2,width(),height() - hght2); -} - -QSize KviLinksWindow::sizeHint() const -{ - QSize ret(m_pSplitter->sizeHint().width(), - m_pSplitter->sizeHint().height() + m_pTopSplitter->sizeHint().height()); - return ret; -} - -void KviLinksWindow::fillCaptionBuffers() -{ - KviQString::sprintf(m_szPlainTextCaption,__tr2qs("Links for %Q [IRC Context %u]"),&m_szRootServer,m_pConsole->context()->id()); -} - -void KviLinksWindow::die() -{ - close(); -} - -void KviLinksWindow::control(int message) -{ - switch(message) - { - case EXTERNAL_SERVER_DATA_PARSER_CONTROL_RESET: reset(); break; - case EXTERNAL_SERVER_DATA_PARSER_CONTROL_ENDOFDATA: endOfLinks(); break; - } -} - -void KviLinksWindow::endOfLinks() -{ - m_pRequestButton->setEnabled(true); - - m_pListView->clear(); - //m_pListView->setSorting(-1); - - outputNoFmt(KVI_OUT_SYSTEMMESSAGE,"======================"); - outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Received end of links.")); - outputNoFmt(KVI_OUT_SYSTEMMESSAGE,"======================"); - - QTreeWidgetItem * it = 0; - QTreeWidgetItem * root = 0; - - int totalHosts = 0; - int totalHops = 0; - int maxHops = 0; - int avgHops = 0; - int directLinks = 0; - int nearLinks = 0; - int brokenLinks = 0; - int maxLinks = 0; - int farLinks = 0; - int wildServers = 0; - - KviCString szMaxHop,szMaxLinks; - - m_pListView->setUpdatesEnabled(false); - for(KviLink *l=m_pLinkList->first();l;l=m_pLinkList->next()){ - totalHosts++; - if(l->hops == 0) - { - root = new QTreeWidgetItem(m_pListView); - root->setText(0,QString(l->host.ptr())); - root->setText(1,QString("0")); - root->setText(2,QString(l->description.ptr())); - } else { - totalHops += l->hops; - if(l->hops < 4){ - nearLinks++; - if(l->hops == 1)directLinks++; - } else { - if(l->hops >= 7)farLinks++; - } - if(l->hops == maxHops){ - szMaxHop.append(','); - szMaxHop.append(l->host); - } else if(l->hops > maxHops){ - maxHops = l->hops; - szMaxHop = l->host; - } - if(l->host.contains('*'))wildServers++; - it = insertLink(l); - if(!it) - { - output(KVI_OUT_SYSTEMERROR,__tr2qs("Broken link: Missing parent (%s) for %s (%d hops): %s (used /LINKS ?)"), - l->parent.ptr(),l->host.ptr(),l->hops,l->description.ptr()); - brokenLinks++; - QString tmp; - KviQString::sprintf(tmp,__tr2qs("%s: Parent link %s"),l->description.ptr(),l->parent.ptr()); - KviCString tmp2(KviCString::Format,"%d",l->hops); - if(root) - { - it = new QTreeWidgetItem(root); - it->setText(0,QString(l->host.ptr())); - it->setText(1,QString(tmp2.ptr())); - it->setText(2,tmp); - } else { - outputNoFmt(KVI_OUT_SYSTEMERROR,__tr2qs("Warning: No root link was sent by the server, the stats may be invalid.")); - it = new QTreeWidgetItem(m_pListView); - it->setText(0,QString(l->host.ptr())); - it->setText(1,QString(tmp2.ptr())); - it->setText(2,tmp); - } - } else { - it = (QTreeWidgetItem*) it->parent(); - if(it) - { - int links = it->childCount() + 1; - if(links == maxLinks) - { - szMaxLinks.append(','); - szMaxLinks.append(it->text(0)); - } else if(links > maxLinks) - { - maxLinks = links; - szMaxLinks = it->text(0); - } - } - } - } - } - - avgHops = ((totalHosts > 0) ? ((totalHops * 100) / totalHosts) : 0 ); - int nearProcent = ((totalHosts > 0) ? ((nearLinks * 10000) / totalHosts) : 0); - int directProcent = ((totalHosts > 0) ? ((directLinks * 10000) / totalHosts) : 0); - int midLinks = totalHosts - (farLinks + nearLinks + 1 + brokenLinks); - if(midLinks < 0)midLinks = 0; - int midProcent = ((totalHosts > 0) ? ((midLinks * 10000) / totalHosts) : 0); - int farProcent = ((totalHosts > 0) ? ((farLinks * 10000) / totalHosts) : 0); - - outputNoFmt(KVI_OUT_LINKS,"======================"); - -// if(!root)root = m_pListView->firstChild(); - if(root) - { - m_szRootServer = root->text(0); - output(KVI_OUT_LINKS,__tr2qs("%c%cLinks for %Q"),KviMircCntrl::Bold,KviMircCntrl::Underline,&m_szRootServer); - outputNoFmt(KVI_OUT_LINKS,"======================"); - QString tmpo = wildServers ? __tr2qs("Total hosts listed") : __tr2qs("Total hosts in the network"); - output(KVI_OUT_LINKS,"%Q: %d",&tmpo,totalHosts); - if(wildServers)output(KVI_OUT_LINKS,__tr2qs("Wildcard servers (hubs?): %d"),wildServers); - output(KVI_OUT_LINKS,__tr2qs("Direct links: %d (~%d.%d %)"),directLinks,directProcent / 100, directProcent % 100); - output(KVI_OUT_LINKS,__tr2qs("Close links (1 <= hops <= 3): %d (~%d.%d %)"),nearLinks,nearProcent / 100,nearProcent % 100); - output(KVI_OUT_LINKS,__tr2qs("Mid-range links (4 <= hops <= 6): %d (~%d.%d %)"),midLinks,midProcent / 100,midProcent % 100); - output(KVI_OUT_LINKS,__tr2qs("Distant links (7 <= hops): %d (~%d.%d %)"),farLinks,farProcent / 100,farProcent % 100); - output(KVI_OUT_LINKS,__tr2qs("Broken (unknown) links: %d"),brokenLinks); - output(KVI_OUT_LINKS,__tr2qs("Maximum links per host: %d [%s]"),maxLinks,szMaxLinks.ptr()); - output(KVI_OUT_LINKS,__tr2qs("Total links: %d"),totalHops); - output(KVI_OUT_LINKS,__tr2qs("Maximum hops: %d [%s]"),maxHops,szMaxHop.ptr()); - output(KVI_OUT_LINKS,__tr2qs("Average hops: ~%d.%d"),avgHops / 100,avgHops % 100); - } else { - m_szRootServer = __tr2qs("(Unknown)"); - outputNoFmt(KVI_OUT_LINKS,__tr2qs("Incomplete LINKS result, no stats available")); - } - outputNoFmt(KVI_OUT_LINKS,"======================"); - - updateCaption(); - - - while(!m_pLinkList->isEmpty())m_pLinkList->removeFirst(); - - m_pListView->resizeColumnToContents(0); - m_pListView->setUpdatesEnabled(true); - m_pListView->repaint(); -} - -QTreeWidgetItem * KviLinksWindow::insertLink(KviLink *l) -{ - KVI_ASSERT(l->hops > 0); - QTreeWidgetItem * i = getItemByHost(l->parent.ptr(),0); - QTreeWidgetItem * it = 0; - if(!i) - { - return 0; - } else { - KviCString hops(KviCString::Format,"%d",l->hops); - it = new QTreeWidgetItem(i); - it->setText(0,QString(l->host.ptr())); - it->setText(1,QString(hops.ptr())); - it->setText(2,QString(l->description.ptr())); - i->setExpanded(true); - } - return it; -} - -QTreeWidgetItem * KviLinksWindow::getItemByHost(const char *host,QTreeWidgetItem * par) -{ - KviCString tmp; - if(par) - { - for(int i=0;ichildCount();i++) - { - tmp = par->child(i)->text(0); - if(kvi_strEqualCI(tmp.ptr(),host))return par->child(i); - QTreeWidgetItem * ch = getItemByHost(host,par->child(i)); - if(ch)return ch; - } - } else { - for(int i=0;itopLevelItemCount();i++) - { - tmp = m_pListView->topLevelItem(i)->text(0); - if(kvi_strEqualCI(tmp.ptr(),host))return m_pListView->topLevelItem(i); - QTreeWidgetItem * ch = getItemByHost(host,m_pListView->topLevelItem(i)); - if(ch)return ch; - } - } - return 0; -} - -void KviLinksWindow::showHostPopup(QTreeWidgetItem *i,const QPoint &p) -{ - if(!i)return; - KviCString host=i->text(0); - if(host.isEmpty())return; - m_pHostPopup->clear(); - KviCString tmp(KviCString::Format,"LINKS %s *",host.ptr()); - m_pHostPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_LINKS)),tmp.ptr()); - m_pHostPopup->insertSeparator(); - tmp.sprintf("TIME %s",host.ptr()); - m_pHostPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),tmp.ptr()); - tmp.sprintf("ADMIN %s",host.ptr()); - m_pHostPopup->insertItem(tmp.ptr()); - tmp.sprintf("INFO %s",host.ptr()); - m_pHostPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_SERVERINFO)),tmp.ptr()); - tmp.sprintf("MOTD %s",host.ptr()); - m_pHostPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MOTD)),tmp.ptr()); - tmp.sprintf("VERSION %s",host.ptr()); - m_pHostPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_KVIRC)),tmp.ptr()); - tmp.sprintf("TRACE %s",host.ptr()); - m_pHostPopup->insertItem(tmp.ptr()); - tmp.sprintf("USERS %s",host.ptr()); - m_pHostPopup->insertItem(tmp.ptr()); - m_pHostPopup->insertSeparator(); - tmp.sprintf("STATS c %s",host.ptr()); - m_pHostPopup->insertItem(tmp.ptr()); - tmp.sprintf("STATS d %s",host.ptr()); - m_pHostPopup->insertItem(tmp.ptr()); - tmp.sprintf("STATS h %s",host.ptr()); - m_pHostPopup->insertItem(tmp.ptr()); - tmp.sprintf("STATS i %s",host.ptr()); - m_pHostPopup->insertItem(tmp.ptr()); - tmp.sprintf("STATS k %s",host.ptr()); - m_pHostPopup->insertItem(tmp.ptr()); - tmp.sprintf("STATS l %s",host.ptr()); - m_pHostPopup->insertItem(tmp.ptr()); - tmp.sprintf("STATS m %s",host.ptr()); - m_pHostPopup->insertItem(tmp.ptr()); - tmp.sprintf("STATS o %s",host.ptr()); - m_pHostPopup->insertItem(tmp.ptr()); - tmp.sprintf("STATS t %s",host.ptr()); - m_pHostPopup->insertItem(tmp.ptr()); - tmp.sprintf("STATS u %s",host.ptr()); - m_pHostPopup->insertItem(tmp.ptr()); - tmp.sprintf("STATS y %s",host.ptr()); - m_pHostPopup->insertItem(tmp.ptr()); - tmp.sprintf("STATS z %s",host.ptr()); - m_pHostPopup->insertItem(tmp.ptr()); - m_pHostPopup->popup(p); -} - -void KviLinksWindow::hostPopupClicked(int id) -{ - KviCString tmp = m_pHostPopup->text(id); - if(tmp.hasData()) - { - if(!connection())output(KVI_OUT_SYSTEMERROR,__tr2qs("You're not connected to a server")); - m_pConsole->connection()->sendData(tmp.ptr()); - } -} - -void KviLinksWindow::reset() -{ - outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Reset")); - while(!m_pLinkList->isEmpty())m_pLinkList->removeFirst(); -} - -void KviLinksWindow::processData(KviIrcMessage *msg) -{ - output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Processing link: %s"),msg->allParams()); - KviLink * l = new KviLink; - - l->host = msg->safeParam(1); - l->parent = msg->safeParam(2); - - const char * tr = msg->safeTrailing(); - - if(isdigit(*tr)) - { - const char *aux = tr; - while(*tr && (isdigit(*tr)))tr++; - KviCString tmp(aux,tr - aux); - l->hops = tmp.toInt(); - } else { - outputNoFmt(KVI_OUT_SYSTEMERROR,__tr2qs("Broken message syntax, can't extract hops number, assuming 0")); - l->hops = 0; - } - while(*tr && (*tr == ' '))tr++; - l->description = tr; - uint idx=0; - for(KviLink *m=m_pLinkList->first();m;m=m_pLinkList->next()) - { - if(m->hops >= l->hops) - { - m_pLinkList->insert(idx,l); - return; - } - idx++; - } - m_pLinkList->append(l); -} - -void KviLinksWindow::applyOptions() -{ - m_pListView->applyOptions(); - m_pInfoLabel->applyOptions(); - m_pIrcView->applyOptions(); - KviWindow::applyOptions(); -} - -KviLinksListView::KviLinksListView(QWidget * par, KviWindow * wnd, const char * txt) -: KviThemedTreeWidget(par, wnd, txt) -{ - header()->setSortIndicatorShown(true); - setColumnCount(3); - setHeaderLabels(QStringList() << __tr2qs("Link") << __tr2qs("Hops") << __tr2qs("Description")); - setRootIsDecorated(true); - setAnimated(true); - setSortingEnabled(true); - setAllColumnsShowFocus(true); -} - -void KviLinksListView::mousePressEvent (QMouseEvent *e) -{ - if (e->button() == Qt::RightButton) - { - QTreeWidgetItem *i=itemAt(e->pos()); - if (i) emit rightButtonPressed(i,QCursor::pos()); - } - KviThemedTreeWidget::mousePressEvent(e); -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_linkswindow.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/links/linkswindow.h b/src/modules/links/linkswindow.h deleted file mode 100644 index ee10aeb80..000000000 --- a/src/modules/links/linkswindow.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef _LINKSWINDOW_H_ -#define _LINKSWINDOW_H_ -//============================================================================= -// -// File : linkswindow.h -// Creation date : Thu Dec 21 2000 12:42:55 CEST by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the linkss of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "KviWindow.h" -#include "KviCString.h" -#include "KviIrcSocket.h" -#include "KviIrcServerParser.h" -#include "KviConsoleWindow.h" -#include "KviIrcContext.h" -#include "KviTalPopupMenu.h" -#include "KviThemedTreeWidget.h" - -#include - -class KviThemedLabel; - -typedef struct _KviLink -{ - KviCString host; - KviCString parent; - int hops; - KviCString description; -} KviLink; - -class KviLinksListView : public KviThemedTreeWidget -{ - Q_OBJECT -public: - KviLinksListView(QWidget * par, KviWindow * wnd, const char * txt); - ~KviLinksListView(){}; -protected: - void mousePressEvent (QMouseEvent *e); -signals: - void rightButtonPressed(QTreeWidgetItem *,QPoint); -}; - -class KviLinksWindow : public KviWindow, public KviExternalServerDataParser -{ - Q_OBJECT -public: - KviLinksWindow(KviMainWindow * lpFrm,KviConsoleWindow * lpConsole); - ~KviLinksWindow(); -protected: - QSplitter * m_pVertSplitter; - QSplitter * m_pTopSplitter; - KviLinksListView * m_pListView; - KviPointerList * m_pLinkList; - KviTalPopupMenu * m_pHostPopup; - QString m_szRootServer; - QToolButton * m_pRequestButton; - KviThemedLabel * m_pInfoLabel; -public: // Methods - virtual void control(int msg); - virtual void processData(KviIrcMessage * msg); - virtual void die(); -protected: - virtual QPixmap * myIconPtr(); - virtual void fillCaptionBuffers(); - virtual void applyOptions(); - virtual void resizeEvent(QResizeEvent *e); - virtual void getBaseLogFileName(QString &buffer); -protected slots: - void showHostPopup(QTreeWidgetItem *i,const QPoint &p); - void hostPopupClicked(int id); - void requestLinks(); - void connectionStateChange(); -public: - virtual QSize sizeHint() const; -private: - void reset(); - void endOfLinks(); - QTreeWidgetItem * insertLink(KviLink * l); - QTreeWidgetItem * getItemByHost(const char *host,QTreeWidgetItem * par); -}; - -#endif //_KVI_LINKSWINDOW_H_ diff --git a/src/modules/list/CMakeLists.txt b/src/modules/list/CMakeLists.txt index eb0ea0d56..43be14744 100644 --- a/src/modules/list/CMakeLists.txt +++ b/src/modules/list/CMakeLists.txt @@ -1,12 +1,12 @@ # CMakeLists for src/modules/list SET(kvilist_MOC_HDRS - listwindow.h + ListWindow.h ) SET(kvilist_SRCS libkvilist.cpp - listwindow.cpp + ListWindow.cpp ) # After this call, files will be moc'ed to moc_kvi_*.cpp diff --git a/src/modules/list/ListWindow.cpp b/src/modules/list/ListWindow.cpp new file mode 100644 index 000000000..3e596cb3c --- /dev/null +++ b/src/modules/list/ListWindow.cpp @@ -0,0 +1,590 @@ +//============================================================================= +// +// File : ListWindow.cpp +// Creation date : Thu Oct 7 2001 13:27:55 CEST by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the lists of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "ListWindow.h" + +#include "kvi_debug.h" +#include "KviIconManager.h" +#include "KviIrcView.h" +#include "kvi_out.h" +#include "KviOptions.h" +#include "KviLocale.h" +#include "kvi_out.h" +#include "KviMircCntrl.h" +#include "KviThemedLabel.h" +#include "KviOptions.h" +#include "KviIrcConnection.h" +#include "KviIrcConnection.h" +#include "KviQString.h" +#include "KviTopicWidget.h" +#include "KviConfigurationFile.h" +#include "KviFileDialog.h" +#include "KviMessageBox.h" +#include "kvi_fileextensions.h" +#include "KviTalHBox.h" +#include "KviHtmlGenerator.h" +#include "KviThemedLineEdit.h" + +#include +#include +#include +#include +#include +#include +#include // for Qt::escape + +extern KviPointerList * g_pListWindowList; + +ChannelTreeWidgetItemData::ChannelTreeWidgetItemData(const QString & szChan, const QString & szUsers, const QString & szTopic) +{ + m_szChan = szChan; + m_szUsers = szUsers; + m_szTopic = szTopic; +} + +ChannelTreeWidgetItemData::~ChannelTreeWidgetItemData() +{ +} + + +ChannelTreeWidgetItem::ChannelTreeWidgetItem(QTreeWidget * v,ChannelTreeWidgetItemData * pData) +: QTreeWidgetItem(v), m_pData(pData) +{ + setToolTip(0, m_pData->m_szChan); + setToolTip(1, m_pData->m_szUsers); + setToolTip(2, KviHtmlGenerator::convertToHtml(Qt::escape(m_pData->m_szTopic))); +} + +ChannelTreeWidgetItem::~ChannelTreeWidgetItem() +{ +} + +int ChannelTreeWidgetItem::width(const QFontMetrics & fm, const QTreeWidget *, int iColumn) const +{ + switch(iColumn) + { + case 0: + //channel + return fm.width(m_pData->m_szChan); + break; + case 1: + //users + return fm.width(m_pData->m_szUsers.toInt()); + break; + case 2: + default: + //topic + return fm.width(KviMircCntrl::stripControlBytes(m_pData->m_szTopic)); + break; + } +} + +bool ChannelTreeWidgetItem::operator<(const QTreeWidgetItem & other) const +{ + switch(treeWidget()->sortColumn()) + { + case 0: + //channel + return m_pData->m_szChan.toUpper() < ((ChannelTreeWidgetItem*)&other)->itemData()->m_szChan.toUpper(); + break; + case 1: + //users + return m_pData->m_szUsers.toInt() < ((ChannelTreeWidgetItem*)&other)->itemData()->m_szUsers.toInt(); + break; + case 2: + default: + //topic + return KviMircCntrl::stripControlBytes(m_pData->m_szTopic.toUpper()) < KviMircCntrl::stripControlBytes(((ChannelTreeWidgetItem*)&other)->itemData()->m_szTopic.toUpper()); + break; + } +} + +ChannelTreeWidgetItemDelegate::ChannelTreeWidgetItemDelegate(QTreeWidget * pWidget) +: QItemDelegate(pWidget) +{ +} + +ChannelTreeWidgetItemDelegate::~ChannelTreeWidgetItemDelegate() +{ +} + +void ChannelTreeWidgetItemDelegate::paint(QPainter * p, const QStyleOptionViewItem & option, const QModelIndex & index) const +{ + ChannelTreeWidgetItem* obj = static_cast(index.internalPointer()); + + if (option.state & QStyle::State_Selected) + p->fillRect(option.rect, option.palette.brush( QPalette::Highlight ) ); + + //reset the color + p->setPen(option.palette.text().color()); + + switch(index.column()) + { + case 0: + //channel + p->drawText(option.rect, obj->itemData()->m_szChan); + break; + case 1: + //users + p->drawText(option.rect, Qt::AlignHCenter, obj->itemData()->m_szUsers); + break; + case 2: + default: + //topic + KviTopicWidget::paintColoredText(p,obj->itemData()->m_szTopic,option.palette,option.rect); + break; + } +} + +ListWindow::ListWindow(KviMainWindow * lpFrm, KviConsoleWindow * lpConsole) +: KviWindow(KVI_WINDOW_TYPE_LIST,lpFrm,"list",lpConsole), KviExternalServerDataParser() +{ + g_pListWindowList->append(this); + + m_pFlushTimer = 0; + + m_pItemList = new KviPointerList; + m_pItemList->setAutoDelete(false); + + m_pSplitter = new KviTalSplitter(Qt::Horizontal,this); + m_pSplitter->setObjectName("splitter"); + m_pSplitter->setChildrenCollapsible(false); + m_pTopSplitter = new KviTalSplitter(Qt::Horizontal,this); + m_pTopSplitter->setObjectName("top_splitter"); + m_pTopSplitter->setChildrenCollapsible(false); + m_pVertSplitter = new KviTalSplitter(Qt::Vertical,m_pSplitter); + m_pVertSplitter->setObjectName("vsplitter"); + m_pVertSplitter->setChildrenCollapsible(false); + + KviTalHBox * pBox = new KviTalHBox(m_pTopSplitter); + pBox->setSpacing(1); + pBox->setMargin(0); + + m_pOpenButton = new QToolButton(pBox); + m_pOpenButton->setObjectName("import_list"); + m_pOpenButton->setIconSize(QSize(16,16)); + m_pOpenButton->setIcon(QIcon(*(g_pIconManager->getBigIcon(KVI_BIGICON_OPEN)))); + KviTalToolTip::add(m_pOpenButton,__tr2qs("Import List")); + connect(m_pOpenButton,SIGNAL(clicked()),this,SLOT(importList())); + + m_pSaveButton = new QToolButton(pBox); + m_pSaveButton->setObjectName("export_list"); + m_pSaveButton->setIconSize(QSize(16,16)); + m_pSaveButton->setIcon(QIcon(*(g_pIconManager->getBigIcon(KVI_BIGICON_SAVE)))); + KviTalToolTip::add(m_pSaveButton,__tr2qs("Export List")); + connect(m_pSaveButton,SIGNAL(clicked()),this,SLOT(exportList())); + + m_pRequestButton = new QToolButton(pBox); + m_pRequestButton->setObjectName("request_button"); + m_pRequestButton->setIconSize(QSize(16,16)); + m_pRequestButton->setIcon(QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_LIST)))); + KviTalToolTip::add(m_pRequestButton,__tr2qs("Request List")); + connect(m_pRequestButton,SIGNAL(clicked()),this,SLOT(requestList())); + + m_pStopListDownloadButton = new QToolButton(pBox); + m_pStopListDownloadButton->setObjectName("stoplistdownload_button"); + m_pStopListDownloadButton->setIconSize(QSize(16,16)); + m_pStopListDownloadButton->setIcon(QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NICKNAMEPROBLEM)))); + KviTalToolTip::add(m_pStopListDownloadButton,__tr2qs("Stop list download")); + connect(m_pStopListDownloadButton,SIGNAL(clicked()),this,SLOT(stoplistdownload())); + + m_pParamsEdit = new KviThemedLineEdit(pBox, this, "lineedit"); + pBox->setStretchFactor(m_pParamsEdit,1); + KviTalToolTip::add(m_pParamsEdit,__tr2qs("
/LIST command parameters:
Many servers accept special parameters that " \ + "allow you to filter the returned entries.
" \ + "Commonly, masked channel names (*kvirc*) are accepted as parameters, as well as strings " \ + "like c<n or c>n where n is the minimum or maximum of users on the channel.
")); + + connect(m_pParamsEdit,SIGNAL(textEdited(const QString &)),this,SLOT(liveSearch(const QString &))); + + m_pInfoLabel = new KviThemedLabel(m_pTopSplitter, this, "info_label"); + + m_pTreeWidget = new KviThemedTreeWidget(m_pVertSplitter, this, "list_treewidget"); + m_pTreeWidget->setSelectionBehavior(QAbstractItemView::SelectRows); + m_pTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); + m_pTreeWidget->setItemDelegate(new ChannelTreeWidgetItemDelegate(m_pTreeWidget)); + QStringList columnLabels; + columnLabels.append(__tr2qs("Channel")); + columnLabels.append(__tr2qs("Users")); + columnLabels.append(__tr2qs("Topic")); + m_pTreeWidget->setColumnCount(3); + m_pTreeWidget->setHeaderLabels(columnLabels); + m_pTreeWidget->setAllColumnsShowFocus(TRUE); + m_pTreeWidget->setSortingEnabled(TRUE); + m_pTreeWidget->sortItems(0,Qt::AscendingOrder); + connect(m_pTreeWidget,SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),this,SLOT(itemDoubleClicked(QTreeWidgetItem *, int))); + + m_pIrcView = new KviIrcView(m_pVertSplitter,lpFrm,this); + + m_pConsole->context()->setListWindowPointer(this); + connect(m_pConsole->context(),SIGNAL(stateChanged()),this,SLOT(connectionStateChange())); + + connectionStateChange(); +} + +ListWindow::~ListWindow() +{ + g_pListWindowList->removeRef(this); + m_pConsole->context()->setListWindowPointer(0); + + if(m_pFlushTimer) + delete m_pFlushTimer; + m_pItemList->setAutoDelete(true); + delete m_pItemList; +} + +void ListWindow::getBaseLogFileName(QString & szBuffer) +{ + szBuffer.sprintf("LIST_%d",context()->id()); +} + +void ListWindow::requestList() +{ + if(m_pConsole->isConnected()) + { + KviCString parms = m_pParamsEdit->text(); + if(parms.isEmpty()) + m_pConsole->connection()->sendFmtData("list"); + else + m_pConsole->connection()->sendFmtData("list %s",m_pConsole->connection()->encodeText(parms.ptr()).data()); + + outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Sent list request, waiting for reply...")); + m_pRequestButton->setEnabled(false); + } else { + outputNoFmt(KVI_OUT_SYSTEMERROR,__tr2qs("Cannot request list: No active connection")); + } +} + +void ListWindow::stoplistdownload() +{ + if(m_pConsole->isConnected()) + { + m_pConsole->connection()->sendFmtData("list stoplistdownloadnow"); + outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Stopping the list download...")); //G&N mar 2005 + } else { + outputNoFmt(KVI_OUT_SYSTEMERROR,__tr2qs("Cannot stop list download, no active connection.")); + } +} + +void ListWindow::connectionStateChange() +{ + KviIrcContext::State st = m_pConsole->context()->state(); + m_pRequestButton->setEnabled(st == KviIrcContext::Connected); + if(st == KviIrcContext::Connected) + { + QString szTmp; + KviQString::sprintf(szTmp, + __tr2qs("Connected to %s (%s)"), + m_pConsole->connection()->currentServerName().toUtf8().data(), + m_pConsole->currentNetworkName().toUtf8().data()); + m_pInfoLabel->setText(szTmp); + } else { + m_pInfoLabel->setText(__tr2qs("List cannot be requested: Not connected to a server")); + } +} + +QPixmap * ListWindow::myIconPtr() +{ + return g_pIconManager->getSmallIcon(KVI_SMALLICON_LIST); +} + +void ListWindow::resizeEvent(QResizeEvent *) +{ + int iHeight = m_pTopSplitter->sizeHint().height(); + m_pTopSplitter->setGeometry(0,0,width(),iHeight); + m_pSplitter->setGeometry(0,iHeight,width(),height() - iHeight); +} + +QSize ListWindow::sizeHint() const +{ + return m_pSplitter->sizeHint(); +} + +void ListWindow::fillCaptionBuffers() +{ + KviQString::sprintf(m_szPlainTextCaption,__tr2qs("Channel List [IRC Context %u]"),m_pConsole->context()->id()); +} + +void ListWindow::die() +{ + close(); +} + +void ListWindow::exportList() +{ + if(!m_pTreeWidget->topLevelItemCount()) + { + KviMessageBox::warning(__tr2qs("You cannot export an empty list")); + return; + } + + QString szFile; + if(connection()) + { + QString szDate; + QDateTime date = QDateTime::currentDateTime(); + + switch(KVI_OPTION_UINT(KviOption_uintOutputDatetimeFormat)) + { + case 0: + szDate = date.toString("d MMM yyyy hh-mm"); + break; + case 1: + szDate = date.toString(Qt::ISODate); + break; + case 2: + szDate = date.toString(Qt::SystemLocaleDate); + break; + } + KviQString::sprintf(szFile,__tr2qs("Channel list for %Q - %Q"), + &(connection()->currentNetworkName()),&(szDate)); + } else { + szFile = __tr2qs("Channel list"); + } + + if(KviFileDialog::askForSaveFileName(szFile,__tr2qs("Choose filename"),szFile,__tr2qs("Configuration files (*.kvc)"),false,false,true,this)) + { + if(QFileInfo(szFile).completeSuffix() != "kvc") + szFile.append(".kvc"); + + KviConfigurationFile cfg(szFile,KviConfigurationFile::Write); + cfg.clear(); + + ChannelTreeWidgetItem * it; + for(int i=0; i < m_pTreeWidget->topLevelItemCount(); i++) + { + it = (ChannelTreeWidgetItem *)m_pTreeWidget->topLevelItem(i); + cfg.setGroup(it->itemData()->m_szChan); + // Write properties + cfg.writeEntry("topic",it->itemData()->m_szTopic); + cfg.writeEntry("users",it->itemData()->m_szUsers); + } + } +} + +void ListWindow::importList() +{ + QString szFile; + + if(KviFileDialog::askForOpenFileName(szFile,__tr2qs("Choose filename"),QString(),KVI_FILTER_CONFIG,false,false,this)) + { + + m_pItemList->setAutoDelete(true); + m_pItemList->clear(); + m_pItemList->setAutoDelete(false); + + m_pTreeWidget->clear(); + + + KviConfigurationFile cfg(szFile,KviConfigurationFile::Read); + KviConfigurationFileIterator it(*cfg.dict()); + while(it.current()) + { + cfg.setGroup(it.currentKey()); + m_pItemList->append( + new ChannelTreeWidgetItemData( + it.currentKey(), + cfg.readEntry("users","0"), + cfg.readEntry("topic","") + ) + ); + ++it; + } + flush(); + } +} + +void ListWindow::control(int iMsg) +{ + switch(iMsg) + { + case EXTERNAL_SERVER_DATA_PARSER_CONTROL_RESET: + reset(); + break; + case EXTERNAL_SERVER_DATA_PARSER_CONTROL_STARTOFDATA: + startOfList(); + break; + case EXTERNAL_SERVER_DATA_PARSER_CONTROL_ENDOFDATA: + endOfList(); + break; + } +} + +void ListWindow::reset() +{ + outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Reset")); +} + +void ListWindow::endOfList() +{ + if(m_pFlushTimer) + { + delete m_pFlushTimer; + m_pFlushTimer = 0; + } + m_pRequestButton->setEnabled(true); + outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Channels list download finished")); + flush(); // give it the last kick +} + +void ListWindow::startOfList() +{ + m_pItemList->setAutoDelete(true); + m_pItemList->clear(); + m_pItemList->setAutoDelete(false); + + m_pTreeWidget->clear(); + + m_pRequestButton->setEnabled(false); +} + +void ListWindow::liveSearch(const QString & szText) +{ + QRegExp res(szText,Qt::CaseInsensitive,QRegExp::Wildcard); + + ChannelTreeWidgetItem * pItem=0; + for(int i=0; itopLevelItemCount(); i++) + { + pItem = (ChannelTreeWidgetItem*) m_pTreeWidget->topLevelItem(i); + if(pItem->itemData()->m_szChan.contains(res) || + pItem->itemData()->m_szTopic.contains(res)) + { + pItem->setHidden(false); + } else { + pItem->setHidden(true); + } + } +} + +void ListWindow::processData(KviIrcMessage * pMsg) +{ + if(!m_pFlushTimer) + { + m_pFlushTimer = new QTimer(this); + connect(m_pFlushTimer,SIGNAL(timeout()),this,SLOT(flush())); + m_pFlushTimer->start(1000); + m_pRequestButton->setEnabled(false); + } + + if(m_pParamsEdit->text().isEmpty()) + { + m_pItemList->append( + new ChannelTreeWidgetItemData( + pMsg->connection()->decodeText(pMsg->safeParam(1)), + pMsg->connection()->decodeText(pMsg->safeParam(2)), + pMsg->connection()->decodeText(pMsg->safeTrailing())) + ); + } else { + //rfc2812 permits wildcards here (section 3.2.6) + QRegExp res(m_pParamsEdit->text(),Qt::CaseInsensitive,QRegExp::Wildcard); + if( + res.exactMatch(pMsg->connection()->decodeText(pMsg->safeParam(1))) || + res.exactMatch(pMsg->connection()->decodeText(pMsg->safeTrailing())) + ) + { + m_pItemList->append( + new ChannelTreeWidgetItemData( + pMsg->connection()->decodeText(pMsg->safeParam(1)), + pMsg->connection()->decodeText(pMsg->safeParam(2)), + pMsg->connection()->decodeText(pMsg->safeTrailing()) + ) + ); + } + } + + if(_OUTPUT_VERBOSE) + { + QString szTmp = pMsg->connection()->decodeText(pMsg->allParams()); + output(KVI_OUT_LIST,__tr2qs("Processing list: %Q"),&szTmp); + } +} + +void ListWindow::flush() +{ + m_pTreeWidget->setUpdatesEnabled(true); /* for v_scroolbar */ + while(ChannelTreeWidgetItemData * d = m_pItemList->first()) + { + (void)new ChannelTreeWidgetItem(m_pTreeWidget,d); + m_pItemList->removeFirst(); + } + m_pTreeWidget->setUpdatesEnabled(true); + m_pTreeWidget->viewport()->update(); +} + +void ListWindow::itemDoubleClicked(QTreeWidgetItem * it, int) +{ + QString szText = ((ChannelTreeWidgetItem*)it)->itemData()->m_szChan; + + if(szText.isEmpty()) return; + if(!connection()) return; + + QByteArray dat = connection()->encodeText(szText); + if(!dat.data()) return; + + m_pConsole->connection()->sendFmtData("join %s",dat.data()); +} + + +// +//#warning "Load & save properties of this kind of window" + +//void ListWindow::saveProperties() +//{ +// KviWindowProperty p; +// p.rect = externalGeometry(); +// p.isDocked = isAttacched(); +// QValueList l(m_pSplitter->sizes()); +// if(l.count() >= 1)p.splitWidth1 = *(l.at(0)); +// if(l.count() >= 2)p.splitWidth2 = *(l.at(1)); +// p.timestamp = m_pView->timestamp(); +// p.imagesVisible = m_pView->imagesVisible(); +// p.isMaximized = isAttacched() && isMaximized(); +// p.topSplitWidth1 = 0; +// p.topSplitWidth2 = 0; +// p.topSplitWidth3 = 0; +// g_pOptions->m_pWinPropertiesList->setProperty(caption(),&p); +//} +// +//void ListWindow::setProperties(KviWindowProperty *p) +//{ +// QValueList l; +// l.append(p->splitWidth1); +// l.append(p->splitWidth2); +// m_pVertSplitter->setSizes(l); +// m_pIrcView->setTimestamp(p->timestamp); +// m_pIrcView->setShowImages(p->imagesVisible); +//} + +void ListWindow::applyOptions() +{ + m_pTreeWidget->applyOptions(); + m_pIrcView->applyOptions(); + m_pParamsEdit->applyOptions(); + m_pInfoLabel->applyOptions(); + KviWindow::applyOptions(); +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "ListWindow.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/list/ListWindow.h b/src/modules/list/ListWindow.h new file mode 100644 index 000000000..cf8cf3d17 --- /dev/null +++ b/src/modules/list/ListWindow.h @@ -0,0 +1,124 @@ +#ifndef _LISTWINDOW_H_ +#define _LISTWINDOW_H_ +//============================================================================= +// +// File : ListWindow.h +// Creation date : Thu Oct 7 2001 13:27:55 CEST by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the lists of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviWindow.h" +#include "KviCString.h" +#include "KviIrcSocket.h" +#include "KviPointerList.h" +#include "KviIrcServerParser.h" +#include "KviConsoleWindow.h" +#include "KviIrcContext.h" +#include "KviTalPopupMenu.h" +#include "KviThemedTreeWidget.h" + +#include +#include +#include + +class KviThemedLabel; +class KviThemedLineEdit; + +class ChannelTreeWidgetItemDelegate : public QItemDelegate +{ +public: + ChannelTreeWidgetItemDelegate(QTreeWidget * pWidget = 0); + ~ChannelTreeWidgetItemDelegate(); + void paint(QPainter * pPainter, const QStyleOptionViewItem & option, const QModelIndex & index ) const; +}; + +class ChannelTreeWidgetItemData +{ + friend class ChannelTreeWidgetItem; + friend class ListWindow; + friend class ChannelTreeWidgetItemDelegate; +public: + ChannelTreeWidgetItemData(const QString & szChan, const QString & szUsers, const QString & szTopic); + ~ChannelTreeWidgetItemData(); +protected: + QString m_szChan; + QString m_szUsers; + QString m_szTopic; +}; + +class ChannelTreeWidgetItem : public QTreeWidgetItem +{ + friend class ListWindow; +public: + ChannelTreeWidgetItem(QTreeWidget * pWidget, ChannelTreeWidgetItemData * pData); + ~ChannelTreeWidgetItem(); +private: + ChannelTreeWidgetItemData * m_pData; +public: + int width (const QFontMetrics & fm, const QTreeWidget * pWidget, int iColumn) const; + bool operator<(const QTreeWidgetItem & other) const; + inline ChannelTreeWidgetItemData * itemData() { return m_pData; }; +}; + +class ListWindow : public KviWindow, public KviExternalServerDataParser +{ + Q_OBJECT +public: + ListWindow(KviMainWindow * lpFrm, KviConsoleWindow * lpConsole); + ~ListWindow(); +protected: + QSplitter * m_pVertSplitter; + QSplitter * m_pTopSplitter; + KviThemedTreeWidget * m_pTreeWidget; + KviThemedLineEdit * m_pParamsEdit; + QToolButton * m_pRequestButton; + QToolButton * m_pStopListDownloadButton; + QToolButton * m_pOpenButton; + QToolButton * m_pSaveButton; + KviThemedLabel * m_pInfoLabel; + QTimer * m_pFlushTimer; + KviPointerList * m_pItemList; +public: // Methods + virtual void control(int iMsg); + virtual void processData(KviIrcMessage * pMsg); + virtual void die(); + virtual QSize sizeHint() const; +protected: + virtual QPixmap * myIconPtr(); + virtual void fillCaptionBuffers(); + virtual void applyOptions(); + virtual void resizeEvent(QResizeEvent * e); + virtual void getBaseLogFileName(QString & szBuffer); +protected slots: + void flush(); + void itemDoubleClicked(QTreeWidgetItem * it, int); + void requestList(); + void stoplistdownload(); + void connectionStateChange(); + void exportList(); + void importList(); + void liveSearch(const QString & szText); +private: + void reset(); + void endOfList(); + void startOfList(); +}; + +#endif //_KVI_LISTWINDOW_H_ diff --git a/src/modules/list/libkvilist.cpp b/src/modules/list/libkvilist.cpp index 1ea7a0d1a..9491b5bac 100644 --- a/src/modules/list/libkvilist.cpp +++ b/src/modules/list/libkvilist.cpp @@ -21,7 +21,7 @@ // //============================================================================= -#include "listwindow.h" +#include "ListWindow.h" #include "KviModule.h" #include "KviMainWindow.h" @@ -30,7 +30,7 @@ #include -KviPointerList * g_pListWindowList = 0; +KviPointerList * g_pListWindowList = 0; /* @@ -55,7 +55,7 @@ static bool list_kvs_cmd_open(KviKvsModuleCommandCall * c) if(!(c->window()->context()->listWindow())) { - KviListWindow * w = new KviListWindow(c->window()->frame(),c->window()->console()); + ListWindow * w = new ListWindow(c->window()->frame(),c->window()->console()); c->window()->frame()->addWindow(w); } else { c->warning(__tr2qs("List window already open for this IRC context")); @@ -66,7 +66,7 @@ static bool list_kvs_cmd_open(KviKvsModuleCommandCall * c) static bool list_module_init(KviModule * m) { - g_pListWindowList = new KviPointerList; + g_pListWindowList = new KviPointerList; g_pListWindowList->setAutoDelete(false); KVSM_REGISTER_SIMPLE_COMMAND(m,"open",list_kvs_cmd_open); diff --git a/src/modules/list/listwindow.cpp b/src/modules/list/listwindow.cpp deleted file mode 100644 index 1ddcc233a..000000000 --- a/src/modules/list/listwindow.cpp +++ /dev/null @@ -1,590 +0,0 @@ -//============================================================================= -// -// File : listwindow.cpp -// Creation date : Thu Oct 7 2001 13:27:55 CEST by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the lists of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "listwindow.h" - -#include "kvi_debug.h" -#include "KviIconManager.h" -#include "KviIrcView.h" -#include "kvi_out.h" -#include "KviOptions.h" -#include "KviLocale.h" -#include "kvi_out.h" -#include "KviMircCntrl.h" -#include "KviThemedLabel.h" -#include "KviOptions.h" -#include "KviIrcConnection.h" -#include "KviIrcConnection.h" -#include "KviQString.h" -#include "KviTopicWidget.h" -#include "KviConfigurationFile.h" -#include "KviFileDialog.h" -#include "KviMessageBox.h" -#include "kvi_fileextensions.h" -#include "KviTalHBox.h" -#include "KviHtmlGenerator.h" -#include "KviThemedLineEdit.h" - -#include -#include -#include -#include -#include -#include -#include // for Qt::escape - -extern KviPointerList * g_pListWindowList; - -KviChannelTreeWidgetItemData::KviChannelTreeWidgetItemData(const QString & szChan, const QString & szUsers, const QString & szTopic) -{ - m_szChan = szChan; - m_szUsers = szUsers; - m_szTopic = szTopic; -} - -KviChannelTreeWidgetItemData::~KviChannelTreeWidgetItemData() -{ -} - - -KviChannelTreeWidgetItem::KviChannelTreeWidgetItem(QTreeWidget * v,KviChannelTreeWidgetItemData * pData) -: QTreeWidgetItem(v), m_pData(pData) -{ - setToolTip(0, m_pData->m_szChan); - setToolTip(1, m_pData->m_szUsers); - setToolTip(2, KviHtmlGenerator::convertToHtml(Qt::escape(m_pData->m_szTopic))); -} - -KviChannelTreeWidgetItem::~KviChannelTreeWidgetItem() -{ -} - -int KviChannelTreeWidgetItem::width(const QFontMetrics & fm, const QTreeWidget *, int iColumn) const -{ - switch(iColumn) - { - case 0: - //channel - return fm.width(m_pData->m_szChan); - break; - case 1: - //users - return fm.width(m_pData->m_szUsers.toInt()); - break; - case 2: - default: - //topic - return fm.width(KviMircCntrl::stripControlBytes(m_pData->m_szTopic)); - break; - } -} - -bool KviChannelTreeWidgetItem::operator<(const QTreeWidgetItem & other) const -{ - switch(treeWidget()->sortColumn()) - { - case 0: - //channel - return m_pData->m_szChan.toUpper() < ((KviChannelTreeWidgetItem*)&other)->itemData()->m_szChan.toUpper(); - break; - case 1: - //users - return m_pData->m_szUsers.toInt() < ((KviChannelTreeWidgetItem*)&other)->itemData()->m_szUsers.toInt(); - break; - case 2: - default: - //topic - return KviMircCntrl::stripControlBytes(m_pData->m_szTopic.toUpper()) < KviMircCntrl::stripControlBytes(((KviChannelTreeWidgetItem*)&other)->itemData()->m_szTopic.toUpper()); - break; - } -} - -KviChannelTreeWidgetItemDelegate::KviChannelTreeWidgetItemDelegate(QTreeWidget * pWidget) -: QItemDelegate(pWidget) -{ -} - -KviChannelTreeWidgetItemDelegate::~KviChannelTreeWidgetItemDelegate() -{ -} - -void KviChannelTreeWidgetItemDelegate::paint(QPainter * p, const QStyleOptionViewItem & option, const QModelIndex & index) const -{ - KviChannelTreeWidgetItem* obj = static_cast(index.internalPointer()); - - if (option.state & QStyle::State_Selected) - p->fillRect(option.rect, option.palette.brush( QPalette::Highlight ) ); - - //reset the color - p->setPen(option.palette.text().color()); - - switch(index.column()) - { - case 0: - //channel - p->drawText(option.rect, obj->itemData()->m_szChan); - break; - case 1: - //users - p->drawText(option.rect, Qt::AlignHCenter, obj->itemData()->m_szUsers); - break; - case 2: - default: - //topic - KviTopicWidget::paintColoredText(p,obj->itemData()->m_szTopic,option.palette,option.rect); - break; - } -} - -KviListWindow::KviListWindow(KviMainWindow * lpFrm, KviConsoleWindow * lpConsole) -: KviWindow(KVI_WINDOW_TYPE_LIST,lpFrm,"list",lpConsole), KviExternalServerDataParser() -{ - g_pListWindowList->append(this); - - m_pFlushTimer = 0; - - m_pItemList = new KviPointerList; - m_pItemList->setAutoDelete(false); - - m_pSplitter = new KviTalSplitter(Qt::Horizontal,this); - m_pSplitter->setObjectName("splitter"); - m_pSplitter->setChildrenCollapsible(false); - m_pTopSplitter = new KviTalSplitter(Qt::Horizontal,this); - m_pTopSplitter->setObjectName("top_splitter"); - m_pTopSplitter->setChildrenCollapsible(false); - m_pVertSplitter = new KviTalSplitter(Qt::Vertical,m_pSplitter); - m_pVertSplitter->setObjectName("vsplitter"); - m_pVertSplitter->setChildrenCollapsible(false); - - KviTalHBox * pBox = new KviTalHBox(m_pTopSplitter); - pBox->setSpacing(1); - pBox->setMargin(0); - - m_pOpenButton = new QToolButton(pBox); - m_pOpenButton->setObjectName("import_list"); - m_pOpenButton->setIconSize(QSize(16,16)); - m_pOpenButton->setIcon(QIcon(*(g_pIconManager->getBigIcon(KVI_BIGICON_OPEN)))); - KviTalToolTip::add(m_pOpenButton,__tr2qs("Import List")); - connect(m_pOpenButton,SIGNAL(clicked()),this,SLOT(importList())); - - m_pSaveButton = new QToolButton(pBox); - m_pSaveButton->setObjectName("export_list"); - m_pSaveButton->setIconSize(QSize(16,16)); - m_pSaveButton->setIcon(QIcon(*(g_pIconManager->getBigIcon(KVI_BIGICON_SAVE)))); - KviTalToolTip::add(m_pSaveButton,__tr2qs("Export List")); - connect(m_pSaveButton,SIGNAL(clicked()),this,SLOT(exportList())); - - m_pRequestButton = new QToolButton(pBox); - m_pRequestButton->setObjectName("request_button"); - m_pRequestButton->setIconSize(QSize(16,16)); - m_pRequestButton->setIcon(QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_LIST)))); - KviTalToolTip::add(m_pRequestButton,__tr2qs("Request List")); - connect(m_pRequestButton,SIGNAL(clicked()),this,SLOT(requestList())); - - m_pStopListDownloadButton = new QToolButton(pBox); - m_pStopListDownloadButton->setObjectName("stoplistdownload_button"); - m_pStopListDownloadButton->setIconSize(QSize(16,16)); - m_pStopListDownloadButton->setIcon(QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NICKNAMEPROBLEM)))); - KviTalToolTip::add(m_pStopListDownloadButton,__tr2qs("Stop list download")); - connect(m_pStopListDownloadButton,SIGNAL(clicked()),this,SLOT(stoplistdownload())); - - m_pParamsEdit = new KviThemedLineEdit(pBox, this, "lineedit"); - pBox->setStretchFactor(m_pParamsEdit,1); - KviTalToolTip::add(m_pParamsEdit,__tr2qs("
/LIST command parameters:
Many servers accept special parameters that " \ - "allow you to filter the returned entries.
" \ - "Commonly, masked channel names (*kvirc*) are accepted as parameters, as well as strings " \ - "like c<n or c>n where n is the minimum or maximum of users on the channel.
")); - - connect(m_pParamsEdit,SIGNAL(textEdited(const QString &)),this,SLOT(liveSearch(const QString &))); - - m_pInfoLabel = new KviThemedLabel(m_pTopSplitter, this, "info_label"); - - m_pTreeWidget = new KviThemedTreeWidget(m_pVertSplitter, this, "list_treewidget"); - m_pTreeWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - m_pTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); - m_pTreeWidget->setItemDelegate(new KviChannelTreeWidgetItemDelegate(m_pTreeWidget)); - QStringList columnLabels; - columnLabels.append(__tr2qs("Channel")); - columnLabels.append(__tr2qs("Users")); - columnLabels.append(__tr2qs("Topic")); - m_pTreeWidget->setColumnCount(3); - m_pTreeWidget->setHeaderLabels(columnLabels); - m_pTreeWidget->setAllColumnsShowFocus(TRUE); - m_pTreeWidget->setSortingEnabled(TRUE); - m_pTreeWidget->sortItems(0,Qt::AscendingOrder); - connect(m_pTreeWidget,SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),this,SLOT(itemDoubleClicked(QTreeWidgetItem *, int))); - - m_pIrcView = new KviIrcView(m_pVertSplitter,lpFrm,this); - - m_pConsole->context()->setListWindowPointer(this); - connect(m_pConsole->context(),SIGNAL(stateChanged()),this,SLOT(connectionStateChange())); - - connectionStateChange(); -} - -KviListWindow::~KviListWindow() -{ - g_pListWindowList->removeRef(this); - m_pConsole->context()->setListWindowPointer(0); - - if(m_pFlushTimer) - delete m_pFlushTimer; - m_pItemList->setAutoDelete(true); - delete m_pItemList; -} - -void KviListWindow::getBaseLogFileName(QString & szBuffer) -{ - szBuffer.sprintf("LIST_%d",context()->id()); -} - -void KviListWindow::requestList() -{ - if(m_pConsole->isConnected()) - { - KviCString parms = m_pParamsEdit->text(); - if(parms.isEmpty()) - m_pConsole->connection()->sendFmtData("list"); - else - m_pConsole->connection()->sendFmtData("list %s",m_pConsole->connection()->encodeText(parms.ptr()).data()); - - outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Sent list request, waiting for reply...")); - m_pRequestButton->setEnabled(false); - } else { - outputNoFmt(KVI_OUT_SYSTEMERROR,__tr2qs("Cannot request list: No active connection")); - } -} - -void KviListWindow::stoplistdownload() -{ - if(m_pConsole->isConnected()) - { - m_pConsole->connection()->sendFmtData("list stoplistdownloadnow"); - outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Stopping the list download...")); //G&N mar 2005 - } else { - outputNoFmt(KVI_OUT_SYSTEMERROR,__tr2qs("Cannot stop list download, no active connection.")); - } -} - -void KviListWindow::connectionStateChange() -{ - KviIrcContext::State st = m_pConsole->context()->state(); - m_pRequestButton->setEnabled(st == KviIrcContext::Connected); - if(st == KviIrcContext::Connected) - { - QString szTmp; - KviQString::sprintf(szTmp, - __tr2qs("Connected to %s (%s)"), - m_pConsole->connection()->currentServerName().toUtf8().data(), - m_pConsole->currentNetworkName().toUtf8().data()); - m_pInfoLabel->setText(szTmp); - } else { - m_pInfoLabel->setText(__tr2qs("List cannot be requested: Not connected to a server")); - } -} - -QPixmap * KviListWindow::myIconPtr() -{ - return g_pIconManager->getSmallIcon(KVI_SMALLICON_LIST); -} - -void KviListWindow::resizeEvent(QResizeEvent *) -{ - int iHeight = m_pTopSplitter->sizeHint().height(); - m_pTopSplitter->setGeometry(0,0,width(),iHeight); - m_pSplitter->setGeometry(0,iHeight,width(),height() - iHeight); -} - -QSize KviListWindow::sizeHint() const -{ - return m_pSplitter->sizeHint(); -} - -void KviListWindow::fillCaptionBuffers() -{ - KviQString::sprintf(m_szPlainTextCaption,__tr2qs("Channel List [IRC Context %u]"),m_pConsole->context()->id()); -} - -void KviListWindow::die() -{ - close(); -} - -void KviListWindow::exportList() -{ - if(!m_pTreeWidget->topLevelItemCount()) - { - KviMessageBox::warning(__tr2qs("You cannot export an empty list")); - return; - } - - QString szFile; - if(connection()) - { - QString szDate; - QDateTime date = QDateTime::currentDateTime(); - - switch(KVI_OPTION_UINT(KviOption_uintOutputDatetimeFormat)) - { - case 0: - szDate = date.toString("d MMM yyyy hh-mm"); - break; - case 1: - szDate = date.toString(Qt::ISODate); - break; - case 2: - szDate = date.toString(Qt::SystemLocaleDate); - break; - } - KviQString::sprintf(szFile,__tr2qs("Channel list for %Q - %Q"), - &(connection()->currentNetworkName()),&(szDate)); - } else { - szFile = __tr2qs("Channel list"); - } - - if(KviFileDialog::askForSaveFileName(szFile,__tr2qs("Choose filename"),szFile,__tr2qs("Configuration files (*.kvc)"),false,false,true,this)) - { - if(QFileInfo(szFile).completeSuffix() != "kvc") - szFile.append(".kvc"); - - KviConfigurationFile cfg(szFile,KviConfigurationFile::Write); - cfg.clear(); - - KviChannelTreeWidgetItem * it; - for(int i=0; i < m_pTreeWidget->topLevelItemCount(); i++) - { - it = (KviChannelTreeWidgetItem *)m_pTreeWidget->topLevelItem(i); - cfg.setGroup(it->itemData()->m_szChan); - // Write properties - cfg.writeEntry("topic",it->itemData()->m_szTopic); - cfg.writeEntry("users",it->itemData()->m_szUsers); - } - } -} - -void KviListWindow::importList() -{ - QString szFile; - - if(KviFileDialog::askForOpenFileName(szFile,__tr2qs("Choose filename"),QString(),KVI_FILTER_CONFIG,false,false,this)) - { - - m_pItemList->setAutoDelete(true); - m_pItemList->clear(); - m_pItemList->setAutoDelete(false); - - m_pTreeWidget->clear(); - - - KviConfigurationFile cfg(szFile,KviConfigurationFile::Read); - KviConfigurationFileIterator it(*cfg.dict()); - while(it.current()) - { - cfg.setGroup(it.currentKey()); - m_pItemList->append( - new KviChannelTreeWidgetItemData( - it.currentKey(), - cfg.readEntry("users","0"), - cfg.readEntry("topic","") - ) - ); - ++it; - } - flush(); - } -} - -void KviListWindow::control(int iMsg) -{ - switch(iMsg) - { - case EXTERNAL_SERVER_DATA_PARSER_CONTROL_RESET: - reset(); - break; - case EXTERNAL_SERVER_DATA_PARSER_CONTROL_STARTOFDATA: - startOfList(); - break; - case EXTERNAL_SERVER_DATA_PARSER_CONTROL_ENDOFDATA: - endOfList(); - break; - } -} - -void KviListWindow::reset() -{ - outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Reset")); -} - -void KviListWindow::endOfList() -{ - if(m_pFlushTimer) - { - delete m_pFlushTimer; - m_pFlushTimer = 0; - } - m_pRequestButton->setEnabled(true); - outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Channels list download finished")); - flush(); // give it the last kick -} - -void KviListWindow::startOfList() -{ - m_pItemList->setAutoDelete(true); - m_pItemList->clear(); - m_pItemList->setAutoDelete(false); - - m_pTreeWidget->clear(); - - m_pRequestButton->setEnabled(false); -} - -void KviListWindow::liveSearch(const QString & szText) -{ - QRegExp res(szText,Qt::CaseInsensitive,QRegExp::Wildcard); - - KviChannelTreeWidgetItem * pItem=0; - for(int i=0; itopLevelItemCount(); i++) - { - pItem = (KviChannelTreeWidgetItem*) m_pTreeWidget->topLevelItem(i); - if(pItem->itemData()->m_szChan.contains(res) || - pItem->itemData()->m_szTopic.contains(res)) - { - pItem->setHidden(false); - } else { - pItem->setHidden(true); - } - } -} - -void KviListWindow::processData(KviIrcMessage * pMsg) -{ - if(!m_pFlushTimer) - { - m_pFlushTimer = new QTimer(this); - connect(m_pFlushTimer,SIGNAL(timeout()),this,SLOT(flush())); - m_pFlushTimer->start(1000); - m_pRequestButton->setEnabled(false); - } - - if(m_pParamsEdit->text().isEmpty()) - { - m_pItemList->append( - new KviChannelTreeWidgetItemData( - pMsg->connection()->decodeText(pMsg->safeParam(1)), - pMsg->connection()->decodeText(pMsg->safeParam(2)), - pMsg->connection()->decodeText(pMsg->safeTrailing())) - ); - } else { - //rfc2812 permits wildcards here (section 3.2.6) - QRegExp res(m_pParamsEdit->text(),Qt::CaseInsensitive,QRegExp::Wildcard); - if( - res.exactMatch(pMsg->connection()->decodeText(pMsg->safeParam(1))) || - res.exactMatch(pMsg->connection()->decodeText(pMsg->safeTrailing())) - ) - { - m_pItemList->append( - new KviChannelTreeWidgetItemData( - pMsg->connection()->decodeText(pMsg->safeParam(1)), - pMsg->connection()->decodeText(pMsg->safeParam(2)), - pMsg->connection()->decodeText(pMsg->safeTrailing()) - ) - ); - } - } - - if(_OUTPUT_VERBOSE) - { - QString szTmp = pMsg->connection()->decodeText(pMsg->allParams()); - output(KVI_OUT_LIST,__tr2qs("Processing list: %Q"),&szTmp); - } -} - -void KviListWindow::flush() -{ - m_pTreeWidget->setUpdatesEnabled(true); /* for v_scroolbar */ - while(KviChannelTreeWidgetItemData * d = m_pItemList->first()) - { - (void)new KviChannelTreeWidgetItem(m_pTreeWidget,d); - m_pItemList->removeFirst(); - } - m_pTreeWidget->setUpdatesEnabled(true); - m_pTreeWidget->viewport()->update(); -} - -void KviListWindow::itemDoubleClicked(QTreeWidgetItem * it, int) -{ - QString szText = ((KviChannelTreeWidgetItem*)it)->itemData()->m_szChan; - - if(szText.isEmpty()) return; - if(!connection()) return; - - QByteArray dat = connection()->encodeText(szText); - if(!dat.data()) return; - - m_pConsole->connection()->sendFmtData("join %s",dat.data()); -} - - -// -//#warning "Load & save properties of this kind of window" - -//void KviListWindow::saveProperties() -//{ -// KviWindowProperty p; -// p.rect = externalGeometry(); -// p.isDocked = isAttacched(); -// QValueList l(m_pSplitter->sizes()); -// if(l.count() >= 1)p.splitWidth1 = *(l.at(0)); -// if(l.count() >= 2)p.splitWidth2 = *(l.at(1)); -// p.timestamp = m_pView->timestamp(); -// p.imagesVisible = m_pView->imagesVisible(); -// p.isMaximized = isAttacched() && isMaximized(); -// p.topSplitWidth1 = 0; -// p.topSplitWidth2 = 0; -// p.topSplitWidth3 = 0; -// g_pOptions->m_pWinPropertiesList->setProperty(caption(),&p); -//} -// -//void KviListWindow::setProperties(KviWindowProperty *p) -//{ -// QValueList l; -// l.append(p->splitWidth1); -// l.append(p->splitWidth2); -// m_pVertSplitter->setSizes(l); -// m_pIrcView->setTimestamp(p->timestamp); -// m_pIrcView->setShowImages(p->imagesVisible); -//} - -void KviListWindow::applyOptions() -{ - m_pTreeWidget->applyOptions(); - m_pIrcView->applyOptions(); - m_pParamsEdit->applyOptions(); - m_pInfoLabel->applyOptions(); - KviWindow::applyOptions(); -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "listwindow.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/list/listwindow.h b/src/modules/list/listwindow.h deleted file mode 100644 index 0ee5eda83..000000000 --- a/src/modules/list/listwindow.h +++ /dev/null @@ -1,124 +0,0 @@ -#ifndef _LISTWINDOW_H_ -#define _LISTWINDOW_H_ -//============================================================================= -// -// File : listwindow.h -// Creation date : Thu Oct 7 2001 13:27:55 CEST by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the lists of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "KviWindow.h" -#include "KviCString.h" -#include "KviIrcSocket.h" -#include "KviPointerList.h" -#include "KviIrcServerParser.h" -#include "KviConsoleWindow.h" -#include "KviIrcContext.h" -#include "KviTalPopupMenu.h" -#include "KviThemedTreeWidget.h" - -#include -#include -#include - -class KviThemedLabel; -class KviThemedLineEdit; - -class KviChannelTreeWidgetItemDelegate : public QItemDelegate -{ -public: - KviChannelTreeWidgetItemDelegate(QTreeWidget * pWidget = 0); - ~KviChannelTreeWidgetItemDelegate(); - void paint(QPainter * pPainter, const QStyleOptionViewItem & option, const QModelIndex & index ) const; -}; - -class KviChannelTreeWidgetItemData -{ - friend class KviChannelTreeWidgetItem; - friend class KviListWindow; - friend class KviChannelTreeWidgetItemDelegate; -public: - KviChannelTreeWidgetItemData(const QString & szChan, const QString & szUsers, const QString & szTopic); - ~KviChannelTreeWidgetItemData(); -protected: - QString m_szChan; - QString m_szUsers; - QString m_szTopic; -}; - -class KviChannelTreeWidgetItem : public QTreeWidgetItem -{ - friend class KviListWindow; -public: - KviChannelTreeWidgetItem(QTreeWidget * pWidget, KviChannelTreeWidgetItemData * pData); - ~KviChannelTreeWidgetItem(); -private: - KviChannelTreeWidgetItemData * m_pData; -public: - int width (const QFontMetrics & fm, const QTreeWidget * pWidget, int iColumn) const; - bool operator<(const QTreeWidgetItem & other) const; - inline KviChannelTreeWidgetItemData * itemData() { return m_pData; }; -}; - -class KviListWindow : public KviWindow, public KviExternalServerDataParser -{ - Q_OBJECT -public: - KviListWindow(KviMainWindow * lpFrm, KviConsoleWindow * lpConsole); - ~KviListWindow(); -protected: - QSplitter * m_pVertSplitter; - QSplitter * m_pTopSplitter; - KviThemedTreeWidget * m_pTreeWidget; - KviThemedLineEdit * m_pParamsEdit; - QToolButton * m_pRequestButton; - QToolButton * m_pStopListDownloadButton; - QToolButton * m_pOpenButton; - QToolButton * m_pSaveButton; - KviThemedLabel * m_pInfoLabel; - QTimer * m_pFlushTimer; - KviPointerList * m_pItemList; -public: // Methods - virtual void control(int iMsg); - virtual void processData(KviIrcMessage * pMsg); - virtual void die(); - virtual QSize sizeHint() const; -protected: - virtual QPixmap * myIconPtr(); - virtual void fillCaptionBuffers(); - virtual void applyOptions(); - virtual void resizeEvent(QResizeEvent * e); - virtual void getBaseLogFileName(QString & szBuffer); -protected slots: - void flush(); - void itemDoubleClicked(QTreeWidgetItem * it, int); - void requestList(); - void stoplistdownload(); - void connectionStateChange(); - void exportList(); - void importList(); - void liveSearch(const QString & szText); -private: - void reset(); - void endOfList(); - void startOfList(); -}; - -#endif //_KVI_LISTWINDOW_H_ diff --git a/src/modules/logview/CMakeLists.txt b/src/modules/logview/CMakeLists.txt index 2848d5bf1..d413a069e 100644 --- a/src/modules/logview/CMakeLists.txt +++ b/src/modules/logview/CMakeLists.txt @@ -3,13 +3,13 @@ SUBDIRS(caps) SET(kvilogview_MOC_HDRS - logviewmdiwindow.h + LogViewWindow.h ) SET(kvilogview_SRCS libkvilogview.cpp - logviewwidget.cpp - logviewmdiwindow.cpp + LogViewWidget.cpp + LogViewWindow.cpp ) # After this call, files will be moc'ed to moc_kvi_*.cpp diff --git a/src/modules/logview/LogViewWidget.cpp b/src/modules/logview/LogViewWidget.cpp new file mode 100644 index 000000000..094f22168 --- /dev/null +++ b/src/modules/logview/LogViewWidget.cpp @@ -0,0 +1,102 @@ +//============================================================================= +// +// File : LogViewWidget.cpp +// Creation date : Thu Apr 23 2002 17:42:12 by Juanjo Alvarez +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002 Juanjo Alvarez +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "LogViewWidget.h" + +//#include "kvi_debug.h" +#include "KviLocale.h" +#include "KviIconManager.h" +#include "KviApplication.h" +#include "KviQString.h" + +#include +#include +#include + +#ifdef COMPILE_ZLIB_SUPPORT + #include +#endif + +LogListViewItem::LogListViewItem(QTreeWidgetItem * par, LogFile::KviLogTypes type, LogFile * fileData) +: QTreeWidgetItem(par), m_type(type), m_pFileData(fileData) +{ + setText(0,m_pFileData ? m_pFileData->name() : QString()); +} + +LogListViewItem::LogListViewItem(QTreeWidget * par, LogFile::KviLogTypes type, LogFile * fileData) +: QTreeWidgetItem(par), m_type(type), m_pFileData(fileData) +{ + setText(0,m_pFileData ? m_pFileData->name() : QString()); +} + +LogListViewItemFolder::LogListViewItemFolder(QTreeWidgetItem * par, const QString& label) +: LogListViewItem(par,LogFile::Other,0) +{ + setText(0,label); +} + +LogListViewItemType::LogListViewItemType(QTreeWidget * par, LogFile::KviLogTypes type) +: LogListViewItem(par,type,0) +{ + QIcon icon; + QString text; + + switch(m_type) + { + case LogFile::Channel: + icon= QIcon(*g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL)); + text = __tr2qs_ctx("Channel","logview"); + break; + case LogFile::Query: + icon= QIcon(*g_pIconManager->getSmallIcon(KVI_SMALLICON_QUERY)); + text = __tr2qs_ctx("Query","logview"); + break; + case LogFile::DccChat: + icon= QIcon(*g_pIconManager->getSmallIcon(KVI_SMALLICON_DCCMSG)); + text = __tr2qs_ctx("DCC Chat","logview"); + break; + case LogFile::Console: + icon= QIcon(*g_pIconManager->getSmallIcon(KVI_SMALLICON_CONSOLE)); + text = __tr2qs_ctx("Console","logview"); + break; + default: + icon= QIcon(*g_pIconManager->getSmallIcon(KVI_SMALLICON_HELP)); + text = __tr2qs_ctx("Other","logview"); + break; + } + + setIcon(0, icon); + setText(0, text); +} + +LogListViewLog::LogListViewLog(QTreeWidgetItem * par, LogFile::KviLogTypes type, LogFile * fileData) +: LogListViewItem(par,type,fileData) +{ + setText(0, m_pFileData->date().toString("yyyy-MM-dd")); +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "LogViewWidget.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/logview/LogViewWidget.h b/src/modules/logview/LogViewWidget.h new file mode 100644 index 000000000..c1f33e4ea --- /dev/null +++ b/src/modules/logview/LogViewWidget.h @@ -0,0 +1,77 @@ +#ifndef _LOGVIEWWIDGET_H_ +#define _LOGVIEWWIDGET_H_ +//============================================================================= +// +// File : LogViewWidget.h +// Creation date : Thue Apr 23 2002 03:01:53 CET by Juanjo Alvarez +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002 Juanjo Alvarez +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "LogViewWindow.h" + +#include "KviWindow.h" +#include "KviScriptEditor.h" +#include + +class KviScriptEditor; + +class LogListViewItem : public QTreeWidgetItem +{ +public: + LogListViewItem(QTreeWidgetItem * par, LogFile::KviLogTypes type, LogFile * fileData); + LogListViewItem(QTreeWidget * par, LogFile::KviLogTypes type, LogFile * fileData); + ~LogListViewItem() {}; +public: + LogFile::KviLogTypes m_type; + LogFile* m_pFileData; + virtual QString fileName() const { return QString(); }; +}; + +class LogListViewItemFolder : public LogListViewItem +{ +public: + LogListViewItemFolder(QTreeWidgetItem * par, const QString& label); + ~LogListViewItemFolder() {}; +public: +}; + +class LogListViewItemType : public LogListViewItem +{ +public: + LogListViewItemType(QTreeWidget * par, LogFile::KviLogTypes type); + ~LogListViewItemType() {}; +}; + + +class LogListViewLog : public LogListViewItem +{ +public: + LogListViewLog(QTreeWidgetItem * par, LogFile::KviLogTypes type, LogFile * fileData); + ~LogListViewLog() {}; + virtual QString fileName() const { return m_pFileData->fileName(); }; +protected: + bool operator<(const QTreeWidgetItem &other)const + { + return m_pFileData->date() < ((LogListViewLog*)&other)->m_pFileData->date(); + } +}; + +#endif diff --git a/src/modules/logview/LogViewWindow.cpp b/src/modules/logview/LogViewWindow.cpp new file mode 100644 index 000000000..60a4e4da4 --- /dev/null +++ b/src/modules/logview/LogViewWindow.cpp @@ -0,0 +1,567 @@ +//============================================================================= +// +// File : LogViewWindow.cpp +// Creation date : Tue Apr 23 2002 18:08:22 by Juanjo Alvarez +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002 Juanjo Alvarez +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "LogViewWindow.h" +#include "LogViewWidget.h" + +#include "KviIconManager.h" +#include "KviLocale.h" +#include "KviModule.h" +#include "KviOptions.h" +#include "KviMainWindow.h" +#include "KviIrcView.h" +#include "KviQString.h" +#include "KviApplication.h" +#include "KviFileUtils.h" +#include "KviTalPopupMenu.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef COMPILE_ZLIB_SUPPORT + #include +#endif + +#include //for INT_MAX + +extern LogViewWindow * g_pLogViewWindow; + +LogViewWindow::LogViewWindow(KviModuleExtensionDescriptor * d,KviMainWindow * lpFrm) +: KviWindow(KVI_WINDOW_TYPE_LOGVIEW,lpFrm,"logview"), KviModuleExtension(d) +{ + g_pLogViewWindow = this; +// m_pLogViewWidget = new KviLogViewWidget(this); + + m_pSplitter = new KviTalSplitter(Qt::Horizontal,this); + m_pSplitter->setObjectName("main_splitter"); + m_pSplitter->setChildrenCollapsible(false); + + m_pLeftLayout = new KviTalVBox(m_pSplitter); + m_pTabWidget = new QTabWidget(m_pLeftLayout); + m_pBottomLayout = new KviTalHBox(m_pLeftLayout); + m_pProgressBar = new QProgressBar(m_pBottomLayout); + + m_pCancelButton = new QPushButton(m_pBottomLayout); + m_pCancelButton->setText(__tr2qs_ctx("Cancel","logview")); + connect(m_pCancelButton,SIGNAL(clicked()),this,SLOT(abortFilter())); + m_pBottomLayout->setVisible(false); + + m_pIndexTab = new KviTalVBox(m_pTabWidget); + m_pTabWidget->addTab(m_pIndexTab,__tr2qs_ctx("HelpIndex","logview")); + + m_pListView = new LogViewListView(m_pIndexTab); + + connect(m_pListView,SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),this,SLOT(itemSelected(QTreeWidgetItem *,QTreeWidgetItem *))); + connect(m_pListView,SIGNAL(rightButtonPressed(QTreeWidgetItem *,QPoint)), + this,SLOT(rightButtonClicked(QTreeWidgetItem *,QPoint))); + + m_pSearchTab = new QWidget(m_pTabWidget); + m_pTabWidget->addTab(m_pSearchTab,__tr2qs_ctx("Filter","logview")); + + QGridLayout *layout = new QGridLayout(m_pSearchTab); + + m_pShowChannelsCheck = new QCheckBox(__tr2qs_ctx("Show channel logs","logview"),m_pSearchTab); + m_pShowChannelsCheck->setChecked(true); + layout->addWidget(m_pShowChannelsCheck,0,0,1,2); + + m_pShowQueryesCheck = new QCheckBox(__tr2qs_ctx("Show query logs","logview"),m_pSearchTab); + m_pShowQueryesCheck->setChecked(true); + layout->addWidget(m_pShowQueryesCheck,1,0,1,2); + + m_pShowConsolesCheck = new QCheckBox(__tr2qs_ctx("Show console logs","logview"),m_pSearchTab); + m_pShowConsolesCheck->setChecked(true); + layout->addWidget(m_pShowConsolesCheck,2,0,1,2); + + m_pShowDccChatCheck = new QCheckBox(__tr2qs_ctx("Show DCC chat logs","logview"),m_pSearchTab); + m_pShowDccChatCheck->setChecked(true); + layout->addWidget(m_pShowDccChatCheck,3,0,1,2); + + m_pShowOtherCheck = new QCheckBox(__tr2qs_ctx("Show other logs","logview"),m_pSearchTab); + m_pShowOtherCheck->setChecked(true); + layout->addWidget(m_pShowOtherCheck,4,0,1,2); + + QLabel *l; + l = new QLabel(__tr2qs_ctx("Contents filter","logview"),m_pSearchTab); + layout->addWidget(l,5,0,1,2); + + l = new QLabel(__tr2qs_ctx("Log name mask:","logview"),m_pSearchTab); + m_pFileNameMask = new QLineEdit(m_pSearchTab); + connect(m_pFileNameMask,SIGNAL(returnPressed()),this,SLOT(applyFilter())); + layout->addWidget(l,6,0); + layout->addWidget(m_pFileNameMask,6,1); + + l = new QLabel(__tr2qs_ctx("Log contents mask:","logview"),m_pSearchTab); + m_pContentsMask = new QLineEdit(m_pSearchTab); + connect(m_pContentsMask,SIGNAL(returnPressed()),this,SLOT(applyFilter())); + layout->addWidget(l,7,0); + layout->addWidget(m_pContentsMask,7,1); + + m_pEnableFromFilter = new QCheckBox(__tr2qs_ctx("Only older than","logview"),m_pSearchTab); + m_pFromDateEdit = new QDateEdit(m_pSearchTab); + m_pFromDateEdit->setDate(QDate::currentDate()); + layout->addWidget(m_pEnableFromFilter,8,0); + layout->addWidget(m_pFromDateEdit,8,1); + connect(m_pEnableFromFilter,SIGNAL(toggled(bool)),m_pFromDateEdit,SLOT(setEnabled(bool))); + m_pFromDateEdit->setEnabled(false); + + m_pEnableToFilter = new QCheckBox(__tr2qs_ctx("Only newier than","logview"),m_pSearchTab); + m_pToDateEdit = new QDateEdit(m_pSearchTab); + m_pToDateEdit->setDate(QDate::currentDate()); + layout->addWidget(m_pEnableToFilter,9,0); + layout->addWidget(m_pToDateEdit,9,1); + connect(m_pEnableToFilter,SIGNAL(toggled(bool)),m_pToDateEdit,SLOT(setEnabled(bool))); + m_pToDateEdit->setEnabled(false); + + m_pFilterButton = new QPushButton(__tr2qs_ctx("Apply filter","logview"),m_pSearchTab); + connect(m_pFilterButton,SIGNAL(clicked()),this,SLOT(applyFilter())); + layout->addWidget(m_pFilterButton,10,1); + + QWidget *w = new QWidget(m_pSearchTab); + w->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored); + layout->addWidget(w,11,1); + + m_pIrcView = new KviIrcView(m_pSplitter,g_pFrame,this); + m_pIrcView->setMaxBufferSize(INT_MAX); + m_pIrcView->setFocusPolicy(Qt::ClickFocus); + + QList li; + li.append(110); + li.append(width()-110); + m_pSplitter->setSizes(li); + + g_pApp->getLocalKvircDirectory(m_szLogDirectory,KviApplication::Log); + KviQString::ensureLastCharIs(m_szLogDirectory,'/'); // Does this work on Windows? + + m_pTimer = new QTimer(this); + m_pTimer->setSingleShot(true); + m_pTimer->setInterval(0); + connect(m_pTimer, SIGNAL(timeout()), this, SLOT(filterNext())); + //avoid to execute the long time-consuming procedure of log indexing here: + //we could still be inside the context of the "Browse log files" QAction + QTimer::singleShot( 0, this, SLOT(cacheFileList()) ); +} + +LogViewWindow::~LogViewWindow() +{ + g_pLogViewWindow = 0; +} + +void LogViewWindow::keyPressEvent(QKeyEvent *e) +{ +//Make CtrlKey and CommandKey ("Apple") behave equally on MacOSX. +//This way typical X11 and Apple shortcuts can be used simultanously within the input line. + if((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::AltModifier) || (e->modifiers() & Qt::MetaModifier)) + { + if(e->key() == Qt::Key_F) + { + m_pIrcView->toggleToolWidget(); + return; + } + } + KviWindow::keyPressEvent(e); +} + +void LogViewWindow::applyFilter() +{ + setupItemList(); +} + +QPixmap * LogViewWindow::myIconPtr() +{ + return g_pIconManager->getSmallIcon(KVI_SMALLICON_LOG); +} + +void LogViewWindow::resizeEvent(QResizeEvent *) +{ + m_pSplitter->setGeometry(0,0,width(),height()); +} + +void LogViewWindow::fillCaptionBuffers() +{ + m_szPlainTextCaption = __tr2qs_ctx("Log Viewer","logview"); +} + +void LogViewWindow::die() +{ + close(); +} + +QSize LogViewWindow::sizeHint() const +{ + QSize ret(m_pSplitter->sizeHint().width(),m_pIrcView->sizeHint().height()); + return ret; +} + +void LogViewWindow::setupItemList() +{ + if(m_logList.isEmpty()) + return; + + m_pFilterButton->setEnabled(false); + m_pListView->clear(); + + m_bAborted=false; + m_pBottomLayout->setVisible(true); + m_pProgressBar->setRange(0, m_logList.count()); + m_pProgressBar->setValue(0); + + m_pLastCategory=0; + m_pLastGroupItem=0; + m_logList.first(); + m_pTimer->start(); //singleshot +} + +void LogViewWindow::abortFilter() +{ + m_bAborted=true; +} + +void LogViewWindow::filterNext() +{ + QString szCurGroup; + LogFile * pFile=m_logList.current(); + if(!pFile) + goto filter_last; + + if(pFile->type()==LogFile::Channel && !m_pShowChannelsCheck->isChecked()) + goto filter_next; + if(pFile->type()==LogFile::Console && !m_pShowConsolesCheck->isChecked()) + goto filter_next; + if(pFile->type()==LogFile::DccChat && !m_pShowDccChatCheck->isChecked()) + goto filter_next; + if(pFile->type()==LogFile::Other && !m_pShowOtherCheck->isChecked()) + goto filter_next; + if(pFile->type()==LogFile::Query && !m_pShowQueryesCheck->isChecked()) + goto filter_next; + + if(m_pEnableFromFilter->isChecked()) + if(pFile->date()>m_pFromDateEdit->date()) + goto filter_next; + + if(m_pEnableToFilter->isChecked()) + if(pFile->date()date()) + goto filter_next; + + if(!m_pFileNameMask->text().isEmpty()) + if(!KviQString::matchString(m_pFileNameMask->text(),pFile->name())) + goto filter_next; + + if(!m_pContentsMask->text().isEmpty()) + { + QString textBuffer; + pFile->getText(textBuffer,m_szLogDirectory); + if(!KviQString::matchString(m_pContentsMask->text(),textBuffer)) + goto filter_next; + } + + if(m_pLastCategory) + { + if(m_pLastCategory->m_type!=pFile->type()) + m_pLastCategory = new LogListViewItemType(m_pListView,pFile->type()); + } else { + m_pLastCategory = new LogListViewItemType(m_pListView,pFile->type()); + } + + KviQString::sprintf(szCurGroup, __tr2qs_ctx("%Q on %Q","logview"), &(pFile->name()), &(pFile->network())); + + if(m_szLastGroup!=szCurGroup) + { + m_szLastGroup=szCurGroup; + m_pLastGroupItem=new LogListViewItemFolder(m_pLastCategory,m_szLastGroup); + } + + new LogListViewLog(m_pLastGroupItem,pFile->type(),pFile); + +filter_next: + pFile = m_logList.next(); + +filter_last: + if(pFile && !m_bAborted) + { + m_pProgressBar->setValue(m_pProgressBar->value()+1); + m_pTimer->start(); //singleshot + } else { + m_pBottomLayout->setVisible(false); + m_pListView->sortItems(0, Qt::AscendingOrder); + m_pProgressBar->setValue(0); + m_pFilterButton->setEnabled(true); + } +} + +void LogViewWindow::cacheFileList() +{ + QStringList m_pFileNames = getFileNames(); + m_pFileNames.sort(); + QString szFname; + + for(QStringList::Iterator it = m_pFileNames.begin(); it != m_pFileNames.end(); ++it) + { + szFname=(*it); + QFileInfo fi(szFname); + if(fi.suffix()=="gz" || fi.suffix()=="log") + m_logList.append(new LogFile(szFname)); + } + + setupItemList(); +} + +void LogViewWindow::itemSelected(QTreeWidgetItem * it,QTreeWidgetItem *) +{ + //A parent node + m_pIrcView->clearBuffer(); + if(!it || !it->parent() || !(((LogListViewItem *)it)->m_pFileData) ) + { + return; + } + + QString text; + ((LogListViewItem *)it)->m_pFileData->getText(text,m_szLogDirectory); + + QStringList lines= text.split('\n'); + bool bOk; + int iMsgType; + for ( QStringList::Iterator it = lines.begin(); it != lines.end(); ++it ) { + QString num=(*it).section(' ',0,0); + iMsgType=num.toInt(&bOk); + if(bOk) + outputNoFmt(iMsgType,(*it).section(' ',1),KviIrcView::NoRepaint | KviIrcView::NoTimestamp); + else + outputNoFmt(0,*it,KviIrcView::NoRepaint | KviIrcView::NoTimestamp); + } + m_pIrcView->repaint(); +} + +QStringList LogViewWindow::getFileNames() +{ + QString logPath; + g_pApp->getLocalKvircDirectory(logPath,KviApplication::Log); + QString qPath(logPath); + QDir logDir(qPath); + return logDir.entryList(); +} + +void LogViewWindow::rightButtonClicked ( QTreeWidgetItem * it, const QPoint &) +{ + if(!it) return; + m_pListView->setCurrentItem(it); + + KviTalPopupMenu* popup = new KviTalPopupMenu(this); + if(((LogListViewItem *)it)->childCount()) + popup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),__tr2qs_ctx("Remove all these channel/query log files","logview"),this,SLOT(deleteCurrent())); + else popup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),__tr2qs_ctx("Remove file","logview"),this,SLOT(deleteCurrent())); + + popup->exec( QCursor::pos() ); +} + +void LogViewWindow::deleteCurrent() +{ + LogListViewItem* pItem = (LogListViewItem *)(m_pListView->currentItem()); + if(pItem) + { + if (pItem->childCount()) + { + if(QMessageBox::question( + this, + __tr2qs("Confirm current user logs delete"), + "Do you really wish to delete all these channel/query logs?", __tr2qs("&Yes"), __tr2qs("&No"),0,1 + ) != 0) return; + KviPointerList itemsList; + itemsList.setAutoDelete(false); + for(int i=0;ichildCount();i++) + { + if (!pItem->child(i)->childCount()) + { + itemsList.append((LogListViewItem*)pItem->child(i)); + continue; + } + LogListViewItem* pChild=(LogListViewItem*)pItem->child(i); + for(int j=0;jchildCount();j++) + { + if (!(LogListViewItem*)pChild->child(j)) + { + qDebug("Null pointer in logviewitem"); + continue; + } + itemsList.append((LogListViewItem*)pChild->child(j)); + } + } + for(unsigned int i=0;ifileName().isNull()) + { + QString szFname; + g_pApp->getLocalKvircDirectory(szFname,KviApplication::Log,pCurItem->fileName()); + KviFileUtils::removeFile(szFname); + } + } + delete pItem; + return; + } + if(!pItem->fileName().isNull()) + { + QString szFname; + g_pApp->getLocalKvircDirectory(szFname,KviApplication::Log,pItem->fileName()); + KviFileUtils::removeFile(szFname); + delete pItem; + m_pIrcView->clearBuffer(); + if (!pItem->parent()->childCount()) delete pItem->parent(); + } + } +} + +LogFile::LogFile(const QString & szName) +{ + /* + Log is in the format + $type_$nick.$network_$YYYY.$MM.$DD.log + Examples: + query_noldor.azzurra_2009.05.20.log + channel_#slackware.azzurra_2009.11.03.log + */ + + QString szTmpName = szName; + m_szFilename = szName; + + QFileInfo fi(m_szFilename); + m_bCompressed = (fi.suffix() == "gz"); + if(m_bCompressed) + { + //removes trailing dot and extension + szTmpName.chop(3); + } + QString szTypeToken = szTmpName.section('_',0,0); + // Ignore non-logs files, this includes '.' and '..' + if(KviQString::equalCI(szTypeToken,"channel")) + m_type = Channel; + else if(KviQString::equalCI(szTypeToken,"console")) + m_type = Console; + else if(KviQString::equalCI(szTypeToken,"dccchat")) + m_type = DccChat; + else if(KviQString::equalCI(szTypeToken,"query")) + m_type = Query; + else + m_type = Other; + + KviCString szUndecoded = szTmpName.section('.',0,0); + szUndecoded.cutToFirst('_'); + m_szName = szUndecoded.hexDecode(szUndecoded.ptr()).ptr(); + + szUndecoded = szTmpName.section('.',1).section('_',0,-2); + m_szNetwork = szUndecoded.hexDecode(szUndecoded.ptr()).ptr(); + + QString szDate = szTmpName.section('_',-1).section('.',0,-2); + int iYear = szDate.section('.',0,0).toInt(); + int iMonth = szDate.section('.',1,1).toInt(); + int iDay = szDate.section('.',2,2).toInt(); + m_date.setYMD(iYear,iMonth,iDay); + + //qDebug("type=%i, name=%s, net=%s, date=%i %i %i",m_type,m_szName.ascii(),m_szNetwork.ascii(),iYear,iMonth,iDay); +} + +void LogFile::getText(QString & text,const QString& logDir){ + QString logName = logDir; + QFile logFile; + logName.append(fileName()); +#ifdef COMPILE_ZLIB_SUPPORT + if(m_bCompressed) + { + gzFile file=gzopen(logName.toLocal8Bit().data(),"rb"); + if(file) + { + char buff[1025]; + int len; + QByteArray data; + //QCString data; + len=gzread(file,buff,1024); + while(len>0) + { + buff[len]=0; + data.append(buff); + len=gzread(file,buff,1024); + } + gzclose(file); + text = QString::fromUtf8(data); + } else { + qDebug("Cannot open compressed file %s",logName.toLocal8Bit().data()); + } + } else { +#endif + logFile.setFileName(logName); + + if(!logFile.open(QIODevice::ReadOnly)) + return; + + QByteArray bytes; + bytes=logFile.readAll(); + text = QString::fromUtf8(bytes.data(), bytes.size()); + logFile.close(); +#ifdef COMPILE_ZLIB_SUPPORT + } +#endif +} + +LogViewListView::LogViewListView(QWidget * par) +: QTreeWidget(par) +{ + header()->setSortIndicatorShown(true); + setColumnCount(1); + setHeaderLabel(__tr2qs_ctx("Log File","logview")); + setSelectionMode(QAbstractItemView::SingleSelection); + setSortingEnabled(true); + setRootIsDecorated(true); + setAnimated(true); +} + +void LogViewListView::mousePressEvent (QMouseEvent *e) +{ + if (e->button() == Qt::RightButton) + { + QTreeWidgetItem *i=itemAt(e->pos()); + if (i) emit rightButtonPressed(i,QCursor::pos()); + } + QTreeWidget::mousePressEvent(e); +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "LogViewWindow.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/logview/LogViewWindow.h b/src/modules/logview/LogViewWindow.h new file mode 100644 index 000000000..34cf55e6b --- /dev/null +++ b/src/modules/logview/LogViewWindow.h @@ -0,0 +1,153 @@ +#ifndef _LOGVIEWMDIWINDOW_H_ +#define _LOGVIEWMDIWINDOW_H_ +//============================================================================= +// +// File : LogViewWindow.h +// Creation date : Tue Apr 23 2002 18:05:59 by Juanjo Alvarez +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002 Juanjo Alvarez +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" +#include "KviWindow.h" +#include "KviModuleExtension.h" +#include "KviTalVBox.h" +#include +#include "KviPointerList.h" + +#include +#include +#include + +class QProgressBar; +class QStringList; +class QLineEdit; +class QDateEdit; +class KviLogViewWidget; +class LogListViewItem; +class LogListViewItemFolder; + +class LogFile { + +public: + + enum KviLogTypes { + Channel, + Console, + Query, + DccChat, + Other + }; + + LogFile(const QString& name); + + const QString & fileName() const { return m_szFilename; }; + const QString & name() const { return m_szName; }; + const QString & network() const { return m_szNetwork; }; + const QDate & date() const { return m_date; }; + + void getText(QString & text,const QString& logDir); + + KviLogTypes type() const { return m_type; }; +private: + KviLogTypes m_type; + QString m_szFilename; + bool m_bCompressed; + QString m_szName; + QString m_szNetwork; + QDate m_date; +}; + +class LogViewListView : public QTreeWidget +{ + Q_OBJECT +public: + LogViewListView(QWidget*); + ~LogViewListView(){}; +protected: + void mousePressEvent (QMouseEvent *e); +signals: + void rightButtonPressed(QTreeWidgetItem *,QPoint); +}; + +class LogViewWindow : public KviWindow, public KviModuleExtension +{ + Q_OBJECT +public: + LogViewWindow(KviModuleExtensionDescriptor * d,KviMainWindow * lpFrm); + ~LogViewWindow(); +protected: + KviPointerList m_logList; + + LogViewListView * m_pListView; + + // Type filter + QCheckBox * m_pShowChannelsCheck; + QCheckBox * m_pShowQueryesCheck; + QCheckBox * m_pShowConsolesCheck; + QCheckBox * m_pShowOtherCheck; + QCheckBox * m_pShowDccChatCheck; + + // Content filter + QLineEdit * m_pFileNameMask; + QLineEdit * m_pContentsMask; + + // Date/time mask + QCheckBox * m_pEnableFromFilter; + QCheckBox * m_pEnableToFilter; + QDateEdit * m_pFromDateEdit; + QDateEdit * m_pToDateEdit; + + QStringList * m_pFileNames; + QString m_szLogDirectory; + QTabWidget * m_pTabWidget; + KviTalVBox * m_pIndexTab; + KviTalVBox * m_pLeftLayout; + QWidget * m_pSearchTab; + QPushButton * m_pFilterButton; + QPushButton * m_pCancelButton; + KviTalHBox * m_pBottomLayout; + QProgressBar * m_pProgressBar; + LogListViewItem * m_pLastCategory; + LogListViewItemFolder *m_pLastGroupItem; + QString m_szLastGroup; + bool m_bAborted; + QTimer * m_pTimer; +protected: + QStringList getFileNames(); + + void setupItemList(); + virtual QPixmap * myIconPtr(); + virtual void resizeEvent(QResizeEvent *e); + virtual void keyPressEvent(QKeyEvent *e); + virtual void fillCaptionBuffers(); + virtual void die(); + virtual QSize sizeHint() const; +protected slots: + void rightButtonClicked ( QTreeWidgetItem *, const QPoint &); + void itemSelected(QTreeWidgetItem * it, QTreeWidgetItem *); + void deleteCurrent(); + void applyFilter(); + void abortFilter(); + void cacheFileList(); + void filterNext(); +}; + +#endif //_LOGVIEWMDIWINDOW_H_ diff --git a/src/modules/logview/libkvilogview.cpp b/src/modules/logview/libkvilogview.cpp index b7b88a71e..3148da280 100644 --- a/src/modules/logview/libkvilogview.cpp +++ b/src/modules/logview/libkvilogview.cpp @@ -22,8 +22,8 @@ // //============================================================================= -#include "logviewwidget.h" -#include "logviewmdiwindow.h" +#include "LogViewWidget.h" +#include "LogViewWindow.h" #include "KviConfigurationFile.h" #include "KviModule.h" @@ -33,7 +33,7 @@ #include "KviApplication.h" static QRect g_rectLogViewGeometry; -KviLogViewMDIWindow * g_pLogViewWindow = 0; +LogViewWindow * g_pLogViewWindow = 0; #define LOGVIEW_MODULE_EXTENSION_NAME "Log viewer extension" @@ -100,7 +100,7 @@ static KviModuleExtension * logview_extension_alloc(KviModuleExtensionAllocStruc } } - g_pLogViewWindow = new KviLogViewMDIWindow(s->pDescriptor,g_pFrame); + g_pLogViewWindow = new LogViewWindow(s->pDescriptor,g_pFrame); g_pFrame->addWindow(g_pLogViewWindow,!bCreateMinimized); if(bCreateMinimized)g_pLogViewWindow->minimize(); return g_pLogViewWindow; diff --git a/src/modules/logview/logviewmdiwindow.cpp b/src/modules/logview/logviewmdiwindow.cpp deleted file mode 100644 index 19fd41173..000000000 --- a/src/modules/logview/logviewmdiwindow.cpp +++ /dev/null @@ -1,567 +0,0 @@ -//============================================================================= -// -// File : logviewmdiwindow.cpp -// Creation date : Tue Apr 23 2002 18:08:22 by Juanjo Alvarez -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2002 Juanjo Alvarez -// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "logviewmdiwindow.h" -#include "logviewwidget.h" - -#include "KviIconManager.h" -#include "KviLocale.h" -#include "KviModule.h" -#include "KviOptions.h" -#include "KviMainWindow.h" -#include "KviIrcView.h" -#include "KviQString.h" -#include "KviApplication.h" -#include "KviFileUtils.h" -#include "KviTalPopupMenu.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef COMPILE_ZLIB_SUPPORT - #include -#endif - -#include //for INT_MAX - -extern KviLogViewMDIWindow * g_pLogViewWindow; - -KviLogViewMDIWindow::KviLogViewMDIWindow(KviModuleExtensionDescriptor * d,KviMainWindow * lpFrm) -: KviWindow(KVI_WINDOW_TYPE_LOGVIEW,lpFrm,"logview"), KviModuleExtension(d) -{ - g_pLogViewWindow = this; -// m_pLogViewWidget = new KviLogViewWidget(this); - - m_pSplitter = new KviTalSplitter(Qt::Horizontal,this); - m_pSplitter->setObjectName("main_splitter"); - m_pSplitter->setChildrenCollapsible(false); - - m_pLeftLayout = new KviTalVBox(m_pSplitter); - m_pTabWidget = new QTabWidget(m_pLeftLayout); - m_pBottomLayout = new KviTalHBox(m_pLeftLayout); - m_pProgressBar = new QProgressBar(m_pBottomLayout); - - m_pCancelButton = new QPushButton(m_pBottomLayout); - m_pCancelButton->setText(__tr2qs_ctx("Cancel","logview")); - connect(m_pCancelButton,SIGNAL(clicked()),this,SLOT(abortFilter())); - m_pBottomLayout->setVisible(false); - - m_pIndexTab = new KviTalVBox(m_pTabWidget); - m_pTabWidget->addTab(m_pIndexTab,__tr2qs_ctx("Index","logview")); - - m_pListView = new KviLogViewListView(m_pIndexTab); - - connect(m_pListView,SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),this,SLOT(itemSelected(QTreeWidgetItem *,QTreeWidgetItem *))); - connect(m_pListView,SIGNAL(rightButtonPressed(QTreeWidgetItem *,QPoint)), - this,SLOT(rightButtonClicked(QTreeWidgetItem *,QPoint))); - - m_pSearchTab = new QWidget(m_pTabWidget); - m_pTabWidget->addTab(m_pSearchTab,__tr2qs_ctx("Filter","logview")); - - QGridLayout *layout = new QGridLayout(m_pSearchTab); - - m_pShowChannelsCheck = new QCheckBox(__tr2qs_ctx("Show channel logs","logview"),m_pSearchTab); - m_pShowChannelsCheck->setChecked(true); - layout->addWidget(m_pShowChannelsCheck,0,0,1,2); - - m_pShowQueryesCheck = new QCheckBox(__tr2qs_ctx("Show query logs","logview"),m_pSearchTab); - m_pShowQueryesCheck->setChecked(true); - layout->addWidget(m_pShowQueryesCheck,1,0,1,2); - - m_pShowConsolesCheck = new QCheckBox(__tr2qs_ctx("Show console logs","logview"),m_pSearchTab); - m_pShowConsolesCheck->setChecked(true); - layout->addWidget(m_pShowConsolesCheck,2,0,1,2); - - m_pShowDccChatCheck = new QCheckBox(__tr2qs_ctx("Show DCC chat logs","logview"),m_pSearchTab); - m_pShowDccChatCheck->setChecked(true); - layout->addWidget(m_pShowDccChatCheck,3,0,1,2); - - m_pShowOtherCheck = new QCheckBox(__tr2qs_ctx("Show other logs","logview"),m_pSearchTab); - m_pShowOtherCheck->setChecked(true); - layout->addWidget(m_pShowOtherCheck,4,0,1,2); - - QLabel *l; - l = new QLabel(__tr2qs_ctx("Contents filter","logview"),m_pSearchTab); - layout->addWidget(l,5,0,1,2); - - l = new QLabel(__tr2qs_ctx("Log name mask:","logview"),m_pSearchTab); - m_pFileNameMask = new QLineEdit(m_pSearchTab); - connect(m_pFileNameMask,SIGNAL(returnPressed()),this,SLOT(applyFilter())); - layout->addWidget(l,6,0); - layout->addWidget(m_pFileNameMask,6,1); - - l = new QLabel(__tr2qs_ctx("Log contents mask:","logview"),m_pSearchTab); - m_pContentsMask = new QLineEdit(m_pSearchTab); - connect(m_pContentsMask,SIGNAL(returnPressed()),this,SLOT(applyFilter())); - layout->addWidget(l,7,0); - layout->addWidget(m_pContentsMask,7,1); - - m_pEnableFromFilter = new QCheckBox(__tr2qs_ctx("Only older than","logview"),m_pSearchTab); - m_pFromDateEdit = new QDateEdit(m_pSearchTab); - m_pFromDateEdit->setDate(QDate::currentDate()); - layout->addWidget(m_pEnableFromFilter,8,0); - layout->addWidget(m_pFromDateEdit,8,1); - connect(m_pEnableFromFilter,SIGNAL(toggled(bool)),m_pFromDateEdit,SLOT(setEnabled(bool))); - m_pFromDateEdit->setEnabled(false); - - m_pEnableToFilter = new QCheckBox(__tr2qs_ctx("Only newier than","logview"),m_pSearchTab); - m_pToDateEdit = new QDateEdit(m_pSearchTab); - m_pToDateEdit->setDate(QDate::currentDate()); - layout->addWidget(m_pEnableToFilter,9,0); - layout->addWidget(m_pToDateEdit,9,1); - connect(m_pEnableToFilter,SIGNAL(toggled(bool)),m_pToDateEdit,SLOT(setEnabled(bool))); - m_pToDateEdit->setEnabled(false); - - m_pFilterButton = new QPushButton(__tr2qs_ctx("Apply filter","logview"),m_pSearchTab); - connect(m_pFilterButton,SIGNAL(clicked()),this,SLOT(applyFilter())); - layout->addWidget(m_pFilterButton,10,1); - - QWidget *w = new QWidget(m_pSearchTab); - w->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored); - layout->addWidget(w,11,1); - - m_pIrcView = new KviIrcView(m_pSplitter,g_pFrame,this); - m_pIrcView->setMaxBufferSize(INT_MAX); - m_pIrcView->setFocusPolicy(Qt::ClickFocus); - - QList li; - li.append(110); - li.append(width()-110); - m_pSplitter->setSizes(li); - - g_pApp->getLocalKvircDirectory(m_szLogDirectory,KviApplication::Log); - KviQString::ensureLastCharIs(m_szLogDirectory,'/'); // Does this work on Windows? - - m_pTimer = new QTimer(this); - m_pTimer->setSingleShot(true); - m_pTimer->setInterval(0); - connect(m_pTimer, SIGNAL(timeout()), this, SLOT(filterNext())); - //avoid to execute the long time-consuming procedure of log indexing here: - //we could still be inside the context of the "Browse log files" QAction - QTimer::singleShot( 0, this, SLOT(cacheFileList()) ); -} - -KviLogViewMDIWindow::~KviLogViewMDIWindow() -{ - g_pLogViewWindow = 0; -} - -void KviLogViewMDIWindow::keyPressEvent(QKeyEvent *e) -{ -//Make CtrlKey and CommandKey ("Apple") behave equally on MacOSX. -//This way typical X11 and Apple shortcuts can be used simultanously within the input line. - if((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::AltModifier) || (e->modifiers() & Qt::MetaModifier)) - { - if(e->key() == Qt::Key_F) - { - m_pIrcView->toggleToolWidget(); - return; - } - } - KviWindow::keyPressEvent(e); -} - -void KviLogViewMDIWindow::applyFilter() -{ - setupItemList(); -} - -QPixmap * KviLogViewMDIWindow::myIconPtr() -{ - return g_pIconManager->getSmallIcon(KVI_SMALLICON_LOG); -} - -void KviLogViewMDIWindow::resizeEvent(QResizeEvent *) -{ - m_pSplitter->setGeometry(0,0,width(),height()); -} - -void KviLogViewMDIWindow::fillCaptionBuffers() -{ - m_szPlainTextCaption = __tr2qs_ctx("Log Viewer","logview"); -} - -void KviLogViewMDIWindow::die() -{ - close(); -} - -QSize KviLogViewMDIWindow::sizeHint() const -{ - QSize ret(m_pSplitter->sizeHint().width(),m_pIrcView->sizeHint().height()); - return ret; -} - -void KviLogViewMDIWindow::setupItemList() -{ - if(m_logList.isEmpty()) - return; - - m_pFilterButton->setEnabled(false); - m_pListView->clear(); - - m_bAborted=false; - m_pBottomLayout->setVisible(true); - m_pProgressBar->setRange(0, m_logList.count()); - m_pProgressBar->setValue(0); - - m_pLastCategory=0; - m_pLastGroupItem=0; - m_logList.first(); - m_pTimer->start(); //singleshot -} - -void KviLogViewMDIWindow::abortFilter() -{ - m_bAborted=true; -} - -void KviLogViewMDIWindow::filterNext() -{ - QString szCurGroup; - KviLogFile * pFile=m_logList.current(); - if(!pFile) - goto filter_last; - - if(pFile->type()==KviLogFile::Channel && !m_pShowChannelsCheck->isChecked()) - goto filter_next; - if(pFile->type()==KviLogFile::Console && !m_pShowConsolesCheck->isChecked()) - goto filter_next; - if(pFile->type()==KviLogFile::DccChat && !m_pShowDccChatCheck->isChecked()) - goto filter_next; - if(pFile->type()==KviLogFile::Other && !m_pShowOtherCheck->isChecked()) - goto filter_next; - if(pFile->type()==KviLogFile::Query && !m_pShowQueryesCheck->isChecked()) - goto filter_next; - - if(m_pEnableFromFilter->isChecked()) - if(pFile->date()>m_pFromDateEdit->date()) - goto filter_next; - - if(m_pEnableToFilter->isChecked()) - if(pFile->date()date()) - goto filter_next; - - if(!m_pFileNameMask->text().isEmpty()) - if(!KviQString::matchString(m_pFileNameMask->text(),pFile->name())) - goto filter_next; - - if(!m_pContentsMask->text().isEmpty()) - { - QString textBuffer; - pFile->getText(textBuffer,m_szLogDirectory); - if(!KviQString::matchString(m_pContentsMask->text(),textBuffer)) - goto filter_next; - } - - if(m_pLastCategory) - { - if(m_pLastCategory->m_type!=pFile->type()) - m_pLastCategory = new KviLogListViewItemType(m_pListView,pFile->type()); - } else { - m_pLastCategory = new KviLogListViewItemType(m_pListView,pFile->type()); - } - - KviQString::sprintf(szCurGroup, __tr2qs_ctx("%Q on %Q","logview"), &(pFile->name()), &(pFile->network())); - - if(m_szLastGroup!=szCurGroup) - { - m_szLastGroup=szCurGroup; - m_pLastGroupItem=new KviLogListViewItemFolder(m_pLastCategory,m_szLastGroup); - } - - new KviLogListViewLog(m_pLastGroupItem,pFile->type(),pFile); - -filter_next: - pFile = m_logList.next(); - -filter_last: - if(pFile && !m_bAborted) - { - m_pProgressBar->setValue(m_pProgressBar->value()+1); - m_pTimer->start(); //singleshot - } else { - m_pBottomLayout->setVisible(false); - m_pListView->sortItems(0, Qt::AscendingOrder); - m_pProgressBar->setValue(0); - m_pFilterButton->setEnabled(true); - } -} - -void KviLogViewMDIWindow::cacheFileList() -{ - QStringList m_pFileNames = getFileNames(); - m_pFileNames.sort(); - QString szFname; - - for(QStringList::Iterator it = m_pFileNames.begin(); it != m_pFileNames.end(); ++it) - { - szFname=(*it); - QFileInfo fi(szFname); - if(fi.suffix()=="gz" || fi.suffix()=="log") - m_logList.append(new KviLogFile(szFname)); - } - - setupItemList(); -} - -void KviLogViewMDIWindow::itemSelected(QTreeWidgetItem * it,QTreeWidgetItem *) -{ - //A parent node - m_pIrcView->clearBuffer(); - if(!it || !it->parent() || !(((KviLogListViewItem *)it)->m_pFileData) ) - { - return; - } - - QString text; - ((KviLogListViewItem *)it)->m_pFileData->getText(text,m_szLogDirectory); - - QStringList lines= text.split('\n'); - bool bOk; - int iMsgType; - for ( QStringList::Iterator it = lines.begin(); it != lines.end(); ++it ) { - QString num=(*it).section(' ',0,0); - iMsgType=num.toInt(&bOk); - if(bOk) - outputNoFmt(iMsgType,(*it).section(' ',1),KviIrcView::NoRepaint | KviIrcView::NoTimestamp); - else - outputNoFmt(0,*it,KviIrcView::NoRepaint | KviIrcView::NoTimestamp); - } - m_pIrcView->repaint(); -} - -QStringList KviLogViewMDIWindow::getFileNames() -{ - QString logPath; - g_pApp->getLocalKvircDirectory(logPath,KviApplication::Log); - QString qPath(logPath); - QDir logDir(qPath); - return logDir.entryList(); -} - -void KviLogViewMDIWindow::rightButtonClicked ( QTreeWidgetItem * it, const QPoint &) -{ - if(!it) return; - m_pListView->setCurrentItem(it); - - KviTalPopupMenu* popup = new KviTalPopupMenu(this); - if(((KviLogListViewItem *)it)->childCount()) - popup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),__tr2qs_ctx("Remove all these channel/query log files","logview"),this,SLOT(deleteCurrent())); - else popup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),__tr2qs_ctx("Remove file","logview"),this,SLOT(deleteCurrent())); - - popup->exec( QCursor::pos() ); -} - -void KviLogViewMDIWindow::deleteCurrent() -{ - KviLogListViewItem* pItem = (KviLogListViewItem *)(m_pListView->currentItem()); - if(pItem) - { - if (pItem->childCount()) - { - if(QMessageBox::question( - this, - __tr2qs("Confirm current user logs delete"), - "Do you really wish to delete all these channel/query logs?", __tr2qs("&Yes"), __tr2qs("&No"),0,1 - ) != 0) return; - KviPointerList itemsList; - itemsList.setAutoDelete(false); - for(int i=0;ichildCount();i++) - { - if (!pItem->child(i)->childCount()) - { - itemsList.append((KviLogListViewItem*)pItem->child(i)); - continue; - } - KviLogListViewItem* pChild=(KviLogListViewItem*)pItem->child(i); - for(int j=0;jchildCount();j++) - { - if (!(KviLogListViewItem*)pChild->child(j)) - { - qDebug("Null pointer in logviewitem"); - continue; - } - itemsList.append((KviLogListViewItem*)pChild->child(j)); - } - } - for(unsigned int i=0;ifileName().isNull()) - { - QString szFname; - g_pApp->getLocalKvircDirectory(szFname,KviApplication::Log,pCurItem->fileName()); - KviFileUtils::removeFile(szFname); - } - } - delete pItem; - return; - } - if(!pItem->fileName().isNull()) - { - QString szFname; - g_pApp->getLocalKvircDirectory(szFname,KviApplication::Log,pItem->fileName()); - KviFileUtils::removeFile(szFname); - delete pItem; - m_pIrcView->clearBuffer(); - if (!pItem->parent()->childCount()) delete pItem->parent(); - } - } -} - -KviLogFile::KviLogFile(const QString & szName) -{ - /* - Log is in the format - $type_$nick.$network_$YYYY.$MM.$DD.log - Examples: - query_noldor.azzurra_2009.05.20.log - channel_#slackware.azzurra_2009.11.03.log - */ - - QString szTmpName = szName; - m_szFilename = szName; - - QFileInfo fi(m_szFilename); - m_bCompressed = (fi.suffix() == "gz"); - if(m_bCompressed) - { - //removes trailing dot and extension - szTmpName.chop(3); - } - QString szTypeToken = szTmpName.section('_',0,0); - // Ignore non-logs files, this includes '.' and '..' - if(KviQString::equalCI(szTypeToken,"channel")) - m_type = Channel; - else if(KviQString::equalCI(szTypeToken,"console")) - m_type = Console; - else if(KviQString::equalCI(szTypeToken,"dccchat")) - m_type = DccChat; - else if(KviQString::equalCI(szTypeToken,"query")) - m_type = Query; - else - m_type = Other; - - KviCString szUndecoded = szTmpName.section('.',0,0); - szUndecoded.cutToFirst('_'); - m_szName = szUndecoded.hexDecode(szUndecoded.ptr()).ptr(); - - szUndecoded = szTmpName.section('.',1).section('_',0,-2); - m_szNetwork = szUndecoded.hexDecode(szUndecoded.ptr()).ptr(); - - QString szDate = szTmpName.section('_',-1).section('.',0,-2); - int iYear = szDate.section('.',0,0).toInt(); - int iMonth = szDate.section('.',1,1).toInt(); - int iDay = szDate.section('.',2,2).toInt(); - m_date.setYMD(iYear,iMonth,iDay); - - //qDebug("type=%i, name=%s, net=%s, date=%i %i %i",m_type,m_szName.ascii(),m_szNetwork.ascii(),iYear,iMonth,iDay); -} - -void KviLogFile::getText(QString & text,const QString& logDir){ - QString logName = logDir; - QFile logFile; - logName.append(fileName()); -#ifdef COMPILE_ZLIB_SUPPORT - if(m_bCompressed) - { - gzFile file=gzopen(logName.toLocal8Bit().data(),"rb"); - if(file) - { - char buff[1025]; - int len; - QByteArray data; - //QCString data; - len=gzread(file,buff,1024); - while(len>0) - { - buff[len]=0; - data.append(buff); - len=gzread(file,buff,1024); - } - gzclose(file); - text = QString::fromUtf8(data); - } else { - qDebug("Cannot open compressed file %s",logName.toLocal8Bit().data()); - } - } else { -#endif - logFile.setFileName(logName); - - if(!logFile.open(QIODevice::ReadOnly)) - return; - - QByteArray bytes; - bytes=logFile.readAll(); - text = QString::fromUtf8(bytes.data(), bytes.size()); - logFile.close(); -#ifdef COMPILE_ZLIB_SUPPORT - } -#endif -} - -KviLogViewListView::KviLogViewListView(QWidget * par) -: QTreeWidget(par) -{ - header()->setSortIndicatorShown(true); - setColumnCount(1); - setHeaderLabel(__tr2qs_ctx("Log File","logview")); - setSelectionMode(QAbstractItemView::SingleSelection); - setSortingEnabled(true); - setRootIsDecorated(true); - setAnimated(true); -} - -void KviLogViewListView::mousePressEvent (QMouseEvent *e) -{ - if (e->button() == Qt::RightButton) - { - QTreeWidgetItem *i=itemAt(e->pos()); - if (i) emit rightButtonPressed(i,QCursor::pos()); - } - QTreeWidget::mousePressEvent(e); -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "logviewmdiwindow.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/logview/logviewmdiwindow.h b/src/modules/logview/logviewmdiwindow.h deleted file mode 100644 index 41ed93285..000000000 --- a/src/modules/logview/logviewmdiwindow.h +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef _LOGVIEWMDIWINDOW_H_ -#define _LOGVIEWMDIWINDOW_H_ -//============================================================================= -// -// File : logviewmdiwindow.h -// Creation date : Tue Apr 23 2002 18:05:59 by Juanjo Alvarez -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2002 Juanjo Alvarez -// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "kvi_settings.h" -#include "KviWindow.h" -#include "KviModuleExtension.h" -#include "KviTalVBox.h" -#include -#include "KviPointerList.h" - -#include -#include -#include - -class QProgressBar; -class QStringList; -class QLineEdit; -class QDateEdit; -class KviLogViewWidget; -class KviLogListViewItem; -class KviLogListViewItemFolder; - -class KviLogFile { - -public: - - enum KviLogTypes { - Channel, - Console, - Query, - DccChat, - Other - }; - - KviLogFile(const QString& name); - - const QString & fileName() const { return m_szFilename; }; - const QString & name() const { return m_szName; }; - const QString & network() const { return m_szNetwork; }; - const QDate & date() const { return m_date; }; - - void getText(QString & text,const QString& logDir); - - KviLogTypes type() const { return m_type; }; -private: - KviLogTypes m_type; - QString m_szFilename; - bool m_bCompressed; - QString m_szName; - QString m_szNetwork; - QDate m_date; -}; - -class KviLogViewListView : public QTreeWidget -{ - Q_OBJECT -public: - KviLogViewListView(QWidget*); - ~KviLogViewListView(){}; -protected: - void mousePressEvent (QMouseEvent *e); -signals: - void rightButtonPressed(QTreeWidgetItem *,QPoint); -}; - -class KviLogViewMDIWindow : public KviWindow, public KviModuleExtension -{ - Q_OBJECT -public: - KviLogViewMDIWindow(KviModuleExtensionDescriptor * d,KviMainWindow * lpFrm); - ~KviLogViewMDIWindow(); -protected: - KviPointerList m_logList; - - KviLogViewListView * m_pListView; - - // Type filter - QCheckBox * m_pShowChannelsCheck; - QCheckBox * m_pShowQueryesCheck; - QCheckBox * m_pShowConsolesCheck; - QCheckBox * m_pShowOtherCheck; - QCheckBox * m_pShowDccChatCheck; - - // Content filter - QLineEdit * m_pFileNameMask; - QLineEdit * m_pContentsMask; - - // Date/time mask - QCheckBox * m_pEnableFromFilter; - QCheckBox * m_pEnableToFilter; - QDateEdit * m_pFromDateEdit; - QDateEdit * m_pToDateEdit; - - QStringList * m_pFileNames; - QString m_szLogDirectory; - QTabWidget * m_pTabWidget; - KviTalVBox * m_pIndexTab; - KviTalVBox * m_pLeftLayout; - QWidget * m_pSearchTab; - QPushButton * m_pFilterButton; - QPushButton * m_pCancelButton; - KviTalHBox * m_pBottomLayout; - QProgressBar * m_pProgressBar; - KviLogListViewItem * m_pLastCategory; - KviLogListViewItemFolder *m_pLastGroupItem; - QString m_szLastGroup; - bool m_bAborted; - QTimer * m_pTimer; -protected: - QStringList getFileNames(); - - void setupItemList(); - virtual QPixmap * myIconPtr(); - virtual void resizeEvent(QResizeEvent *e); - virtual void keyPressEvent(QKeyEvent *e); - virtual void fillCaptionBuffers(); - virtual void die(); - virtual QSize sizeHint() const; -protected slots: - void rightButtonClicked ( QTreeWidgetItem *, const QPoint &); - void itemSelected(QTreeWidgetItem * it, QTreeWidgetItem *); - void deleteCurrent(); - void applyFilter(); - void abortFilter(); - void cacheFileList(); - void filterNext(); -}; - -#endif //_LOGVIEWMDIWINDOW_H_ diff --git a/src/modules/logview/logviewwidget.cpp b/src/modules/logview/logviewwidget.cpp deleted file mode 100644 index 3d8e8642e..000000000 --- a/src/modules/logview/logviewwidget.cpp +++ /dev/null @@ -1,102 +0,0 @@ -//============================================================================= -// -// File : logviewwidget.cpp -// Creation date : Thu Apr 23 2002 17:42:12 by Juanjo Alvarez -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2002 Juanjo Alvarez -// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "logviewwidget.h" - -//#include "kvi_debug.h" -#include "KviLocale.h" -#include "KviIconManager.h" -#include "KviApplication.h" -#include "KviQString.h" - -#include -#include -#include - -#ifdef COMPILE_ZLIB_SUPPORT - #include -#endif - -KviLogListViewItem::KviLogListViewItem(QTreeWidgetItem * par, KviLogFile::KviLogTypes type, KviLogFile * fileData) -: QTreeWidgetItem(par), m_type(type), m_pFileData(fileData) -{ - setText(0,m_pFileData ? m_pFileData->name() : QString()); -} - -KviLogListViewItem::KviLogListViewItem(QTreeWidget * par, KviLogFile::KviLogTypes type, KviLogFile * fileData) -: QTreeWidgetItem(par), m_type(type), m_pFileData(fileData) -{ - setText(0,m_pFileData ? m_pFileData->name() : QString()); -} - -KviLogListViewItemFolder::KviLogListViewItemFolder(QTreeWidgetItem * par, const QString& label) -: KviLogListViewItem(par,KviLogFile::Other,0) -{ - setText(0,label); -} - -KviLogListViewItemType::KviLogListViewItemType(QTreeWidget * par, KviLogFile::KviLogTypes type) -: KviLogListViewItem(par,type,0) -{ - QIcon icon; - QString text; - - switch(m_type) - { - case KviLogFile::Channel: - icon= QIcon(*g_pIconManager->getSmallIcon(KVI_SMALLICON_CHANNEL)); - text = __tr2qs_ctx("Channel","logview"); - break; - case KviLogFile::Query: - icon= QIcon(*g_pIconManager->getSmallIcon(KVI_SMALLICON_QUERY)); - text = __tr2qs_ctx("Query","logview"); - break; - case KviLogFile::DccChat: - icon= QIcon(*g_pIconManager->getSmallIcon(KVI_SMALLICON_DCCMSG)); - text = __tr2qs_ctx("DCC Chat","logview"); - break; - case KviLogFile::Console: - icon= QIcon(*g_pIconManager->getSmallIcon(KVI_SMALLICON_CONSOLE)); - text = __tr2qs_ctx("Console","logview"); - break; - default: - icon= QIcon(*g_pIconManager->getSmallIcon(KVI_SMALLICON_HELP)); - text = __tr2qs_ctx("Other","logview"); - break; - } - - setIcon(0, icon); - setText(0, text); -} - -KviLogListViewLog::KviLogListViewLog(QTreeWidgetItem * par, KviLogFile::KviLogTypes type, KviLogFile * fileData) -: KviLogListViewItem(par,type,fileData) -{ - setText(0, m_pFileData->date().toString("yyyy-MM-dd")); -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "logviewwidget.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/logview/logviewwidget.h b/src/modules/logview/logviewwidget.h deleted file mode 100644 index 9a0a46c34..000000000 --- a/src/modules/logview/logviewwidget.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef _LOGVIEWWIDGET_H_ -#define _LOGVIEWWIDGET_H_ -//============================================================================= -// -// File : logviewwidget.h -// Creation date : Thue Apr 23 2002 03:01:53 CET by Juanjo Alvarez -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2002 Juanjo Alvarez -// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "logviewmdiwindow.h" - -#include "KviWindow.h" -#include "KviScriptEditor.h" -#include - -class KviScriptEditor; - -class KviLogListViewItem : public QTreeWidgetItem -{ -public: - KviLogListViewItem(QTreeWidgetItem * par, KviLogFile::KviLogTypes type, KviLogFile * fileData); - KviLogListViewItem(QTreeWidget * par, KviLogFile::KviLogTypes type, KviLogFile * fileData); - ~KviLogListViewItem() {}; -public: - KviLogFile::KviLogTypes m_type; - KviLogFile* m_pFileData; - virtual QString fileName() const { return QString(); }; -}; - -class KviLogListViewItemFolder : public KviLogListViewItem -{ -public: - KviLogListViewItemFolder(QTreeWidgetItem * par, const QString& label); - ~KviLogListViewItemFolder() {}; -public: -}; - -class KviLogListViewItemType : public KviLogListViewItem -{ -public: - KviLogListViewItemType(QTreeWidget * par, KviLogFile::KviLogTypes type); - ~KviLogListViewItemType() {}; -}; - - -class KviLogListViewLog : public KviLogListViewItem -{ -public: - KviLogListViewLog(QTreeWidgetItem * par, KviLogFile::KviLogTypes type, KviLogFile * fileData); - ~KviLogListViewLog() {}; - virtual QString fileName() const { return m_pFileData->fileName(); }; -protected: - bool operator<(const QTreeWidgetItem &other)const - { - return m_pFileData->date() < ((KviLogListViewLog*)&other)->m_pFileData->date(); - } -}; - -#endif diff --git a/src/modules/mediaplayer/CMakeLists.txt b/src/modules/mediaplayer/CMakeLists.txt index 9ab400403..746132d46 100644 --- a/src/modules/mediaplayer/CMakeLists.txt +++ b/src/modules/mediaplayer/CMakeLists.txt @@ -2,12 +2,12 @@ SET(kvimediaplayer_SRCS libkvimediaplayer.cpp - mp_interface.cpp - mp_mp3.cpp - mp_winampinterface.cpp - mp_xmmsinterface.cpp - mp_amipinterface.cpp - mp_mprisinterface.cpp + MpInterface.cpp + MpMp3.cpp + MpWinampInterface.cpp + MpXmmsInterface.cpp + MpAmipInterface.cpp + MpMprisInterface.cpp ) # After this call, files will be moc'ed to moc_kvi_*.cpp diff --git a/src/modules/mediaplayer/MpAmipInterface.cpp b/src/modules/mediaplayer/MpAmipInterface.cpp new file mode 100644 index 000000000..60c7390f0 --- /dev/null +++ b/src/modules/mediaplayer/MpAmipInterface.cpp @@ -0,0 +1,415 @@ +//============================================================================= +// +// File : MpAmipInterface.cpp +// Creation date : Sun 27 Mar 2005 16:55:09 by Szymon Stefanek +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2005-2010 Szymon Stefanek +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "MpAmipInterface.h" +#include "KviOptions.h" + +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + +#include + +#include "KviLocale.h" +#include "KviModule.h" + +#include + +enum ac_StartMode +{ + AC_START_ALL = 0, + AC_START_CLIENT, + AC_START_SERVER, + AC_START_NONE +}; + +enum ac_ErrorCode +{ + AC_ERR_NOERROR = 0, + AC_ERR_CLIENTISNULL, + AC_ERR_EXCEPTION, + AC_ERR_CONNECTIONFAILED, + AC_ERR_SERVERNOTRUNNING +}; + +#define AC_BUFFER_SIZE 2048 + +static HINSTANCE amip_dll = NULL; + +#define MP_AC_DYNPTR(__rettype,__func,__args) \ + typedef __rettype (CALLBACK* lp_##__func)(__args); \ + lp_##__func __func + +#define MP_AC_FUNC(__func) \ + __func = (lp_##__func)GetProcAddress(amip_dll,#__func); \ + if(!__func) { \ + FreeLibrary(amip_dll); \ + return false; \ + } + +#define COMMA() , + +MP_AC_DYNPTR(void, ac_init, int mode); +MP_AC_DYNPTR(void, ac_uninit, void); +MP_AC_DYNPTR(void, ac_getDestHost, char *out); +MP_AC_DYNPTR(int, ac_getDestPort, void); +MP_AC_DYNPTR(bool, ac_pingServer, const char *host COMMA() int port COMMA() int timeout); +MP_AC_DYNPTR(int, ac_exec, const char *cmd); +MP_AC_DYNPTR(int, ac_eval, const char *cmd COMMA() char *result); + + +static bool loadAmipDll() +{ + amip_dll = LoadLibrary("ac.dll"); + if (!amip_dll) return false; + + MP_AC_FUNC(ac_init); + MP_AC_FUNC(ac_uninit); + MP_AC_FUNC(ac_getDestHost); + MP_AC_FUNC(ac_getDestPort); + MP_AC_FUNC(ac_pingServer); + MP_AC_FUNC(ac_eval); + MP_AC_FUNC(ac_exec); + + return true; +}; + +static QTextCodec * mediaplayer_get_codec() +{ + QTextCodec * c= QTextCodec::codecForName(KVI_OPTION_STRING(KviOption_stringWinampTextEncoding).toAscii()); + if(!c) + c = QTextCodec::codecForLocale(); + return c; +} + +MP_IMPLEMENT_DESCRIPTOR( + MpAmipInterface, + "amip", + __tr2qs_ctx( + "An interface to the AMIP plug-in.\n" \ + "You can download it from http://amip.tools-for.net\n" \ + "To use this interface you must " \ + "install AMIP plug-in for your player." + , + "mediaplayer" + ) +) + + + +MpAmipInterface::MpAmipInterface() +: MpInterface() +{ + if(!amip_dll) { + bool res = loadAmipDll(); + if(!res) { + amip_dll = NULL; + return; + } + ac_init(AC_START_CLIENT); + } +} + +MpAmipInterface::~MpAmipInterface() +{ + if(!amip_dll) return; + ac_uninit(); + FreeLibrary(amip_dll); + amip_dll = NULL; +} + + +int MpAmipInterface::detect(bool bStart) +{ + if(!amip_dll) return 0; + char host[AC_BUFFER_SIZE]; + ac_getDestHost(host); + if(ac_pingServer(host, ac_getDestPort(), 5000)) return 99; + return 1; +} + +#define MP_AMIP_COMMAND(__cmdname,__acmd) \ + bool MpAmipInterface::__cmdname() \ + { \ + return (ac_exec(__acmd) == AC_ERR_NOERROR); \ + } + +MP_AMIP_COMMAND(play,"control play") +MP_AMIP_COMMAND(stop,"control stop") +MP_AMIP_COMMAND(next,"control >") +MP_AMIP_COMMAND(prev,"control <") +MP_AMIP_COMMAND(pause,"control pause") +MP_AMIP_COMMAND(quit,"control exit") + +// helper function for evaluating variables returning integers +int eval_int(const char *var) +{ + if(!amip_dll) return -1; + char buff[AC_BUFFER_SIZE]; + int res = -1; + if (AC_ERR_NOERROR == ac_eval(var, buff)) + res = atoi(buff); + return res; +} + +QString eval_str(const char *var) +{ + QString res; + if(!amip_dll) return res; + char buff[AC_BUFFER_SIZE]; + if (AC_ERR_NOERROR == ac_eval(var, buff)) + res.append(buff); + return res; +} + +int MpAmipInterface::length() +{ + return eval_int("var_sl") * 1000; +} + +int MpAmipInterface::position() +{ + return eval_int("var_psec") * 1000; +} + +int MpAmipInterface::bitRate() +{ + return eval_int("var_br"); +} + +int MpAmipInterface::sampleRate() +{ + return eval_int("var_sr"); +} + +int MpAmipInterface::channels() +{ + int ret = -1; + if(eval_str("var_typ").startsWith("Stereo")) + ret = 2; + else if(eval_str("var_typ").startsWith("Mono")) + ret = 1; + return ret; +} + +MpInterface::PlayerStatus MpAmipInterface::status() +{ + int ret = eval_int("var_stat"); + switch(ret) + { + case 0: + return MpInterface::Stopped; + break; + case 3: + return MpInterface::Paused; + break; + case 1: + return MpInterface::Playing; + break; + default: + return MpInterface::Unknown; + break; + } + return MpInterface::Unknown; +} + +QString MpAmipInterface::mrl() +{ + QString ret; + QString fn = eval_str("var_fn"); + QTextCodec *c=mediaplayer_get_codec(); + if (c) ret = c->toUnicode(fn.toAscii()); + else ret=fn; + if(!ret.startsWith("http://",Qt::CaseInsensitive)) + ret.prepend("file://"); + + return ret; +} + +QString getAmipString(const char * var) +{ + QString ret; + QString s = eval_str(var); + QTextCodec *c=mediaplayer_get_codec(); + if (c) ret = c->toUnicode(s.toAscii()); + else ret=s; + return ret; +} + +QString MpAmipInterface::nowPlaying() +{ + return getAmipString("var_s"); +} + +QString MpAmipInterface::artist() +{ + return getAmipString("var_1"); +} + +QString MpAmipInterface::title() +{ + return getAmipString("var_2"); +} + +QString MpAmipInterface::album() +{ + return getAmipString("var_4"); +} + +QString MpAmipInterface::year() +{ + return getAmipString("var_5"); +} + +QString MpAmipInterface::comment() +{ + return getAmipString("var_6"); +} + +QString MpAmipInterface::genre() +{ + return getAmipString("var_7"); +} + +bool MpAmipInterface::setVol(kvs_int_t &iVol) +{ + if(!amip_dll) return false; + char volcmd[AC_BUFFER_SIZE]; + sprintf(volcmd, "control vol %d", iVol); + return (ac_exec(volcmd) == AC_ERR_NOERROR); +} + +int MpAmipInterface::getVol() +{ + return eval_int("var_vol"); +} + +bool MpAmipInterface::jumpTo(kvs_int_t &iPos) +{ + if(!amip_dll) return false; + char jmpcmd[AC_BUFFER_SIZE]; + sprintf(jmpcmd, "jumptotime %d", iPos/1000); + return (ac_exec(jmpcmd) == AC_ERR_NOERROR); +} +bool MpAmipInterface::hide() +{ + HWND hWinamp = (HWND)eval_int("var_phwnd"); + if(hWinamp && hWinamp != (HWND)-1) + { + ShowWindow(hWinamp, SW_HIDE); + return true; + } + return false; +} + +bool MpAmipInterface::show() +{ + HWND hWinamp = (HWND)eval_int("var_phwnd"); + if(hWinamp && hWinamp != (HWND)-1) + { + ShowWindow(hWinamp, SW_SHOW); + return true; + } + return false; +} + +bool MpAmipInterface::minimize() +{ + if(!amip_dll) return false; + return (ac_exec("control mimimize") == AC_ERR_NOERROR); +} + +bool MpAmipInterface::setPlayListPos(kvs_int_t &iPos) +{ + if(!amip_dll) return false; + char jmpcmd[AC_BUFFER_SIZE]; + sprintf(jmpcmd, "setplpos %d", iPos + 1); + return (ac_exec(jmpcmd) == AC_ERR_NOERROR); +} + +int MpAmipInterface::getPlayListPos() +{ + return eval_int("var_pos"); +} + +int MpAmipInterface::getListLength() +{ + return eval_int("var_ll"); +} + +bool MpAmipInterface::getRepeat() +{ + return eval_str("var_repeat").startsWith("on"); +} + +bool MpAmipInterface::getShuffle() +{ + return eval_str("var_shuffle").startsWith("on"); +} + +bool MpAmipInterface::setShuffle(bool &bVal) +{ + if(!amip_dll) return false; + bool res; + if (bVal) + res = (ac_exec("setshuffle on") == AC_ERR_NOERROR); + else + res = (ac_exec("setshuffle off") == AC_ERR_NOERROR); + return res; +} + +bool MpAmipInterface::setRepeat(bool &bVal) +{ + if(!amip_dll) return false; + bool res; + if (bVal) + res = (ac_exec("setrepeat on") == AC_ERR_NOERROR); + else + res = (ac_exec("setrepeat off") == AC_ERR_NOERROR); + return res; +} + +bool MpAmipInterface::amipExec(const QString &cmd) +{ + if(!amip_dll) return false; + QTextCodec *c=mediaplayer_get_codec(); + KviCString szCmd = c ? c->fromUnicode(cmd) : cmd.toUtf8(); + return (ac_exec(szCmd) == AC_ERR_NOERROR); +} + +QString MpAmipInterface::amipEval(const QString &cmd) +{ + QString ret; + if(!amip_dll) return ret; + QTextCodec *c=mediaplayer_get_codec(); + KviCString szCmd = c ? c->fromUnicode(cmd) : cmd.toUtf8(); + char buff[AC_BUFFER_SIZE]; + if((ac_eval(szCmd, buff) == AC_ERR_NOERROR)) { + QString s = buff; + QTextCodec *c=mediaplayer_get_codec(); + if (c) ret = c->toUnicode(s.toAscii()); + else ret=s; + } + return ret; +} + +#endif //COMPILE_ON_WINDOWS diff --git a/src/modules/mediaplayer/MpAmipInterface.h b/src/modules/mediaplayer/MpAmipInterface.h new file mode 100644 index 000000000..e8a9fac34 --- /dev/null +++ b/src/modules/mediaplayer/MpAmipInterface.h @@ -0,0 +1,81 @@ +#ifndef _MP_AMIPINTERFACE_H_ +#define _MP_AMIPINTERFACE_H_ +//============================================================================= +// +// File : MpAmipInterface.cpp +// Creation date : Sun 27 Mar 2005 16:55:09 by Szymon Stefanek +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2005-2010 Szymon Stefanek +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" + +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + + #include "MpInterface.h" + + class MpAmipInterface : public MpInterface + { + public: + MpAmipInterface(); + ~MpAmipInterface(); + public: + virtual int detect(bool bStart); + virtual bool prev(); + virtual bool next(); + virtual bool play(); + virtual bool stop(); + virtual bool pause(); + virtual bool quit(); + virtual QString nowPlaying(); + virtual QString artist(); + virtual QString title(); + virtual QString genre(); + virtual QString comment(); + virtual QString album(); + virtual QString year(); + virtual QString mrl(); + virtual int position(); + virtual int length(); + virtual bool setVol(kvs_int_t &iVol); + virtual int getVol(); + virtual bool jumpTo(kvs_int_t &iPos); + virtual int sampleRate(); + virtual int bitRate(); + virtual int channels(); + virtual bool hide(); + virtual bool show(); + virtual bool minimize(); + virtual int getPlayListPos(); + virtual bool setPlayListPos(kvs_int_t &iPos); + virtual int getListLength(); + virtual bool getRepeat(); + virtual bool getShuffle(); + virtual bool setRepeat(bool &bVal); + virtual bool setShuffle(bool &bVal); + virtual bool amipExec(const QString &cmd); + virtual QString amipEval(const QString &cmd); + virtual MpInterface::PlayerStatus status(); + }; + + MP_DECLARE_DESCRIPTOR(MpAmipInterface) + +#endif //COMPILE_ON_WINDOWS + +#endif //!_MP_AMIPINTERFACE_H_ diff --git a/src/modules/mediaplayer/MpInterface.cpp b/src/modules/mediaplayer/MpInterface.cpp new file mode 100644 index 000000000..f5a1f569c --- /dev/null +++ b/src/modules/mediaplayer/MpInterface.cpp @@ -0,0 +1,275 @@ +//============================================================================= +// +// File : MpInterface.cpp +// Creation date : Fri Mar 25 20:01:25 2005 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "MpInterface.h" +#include "MpMp3.h" + +#include "KviOptions.h" +#include "KviLocale.h" + +#include + +static QTextCodec * mediaplayer_get_codec() +{ + QTextCodec * c= QTextCodec::codecForName(KVI_OPTION_STRING(KviOption_stringWinampTextEncoding).toUtf8().data()); + if(!c)c = QTextCodec::codecForLocale(); + return c; + +} + +void MpInterface::notImplemented() +{ + setLastError(__tr2qs_ctx("Function not implemented","mediaplayer")); +} + +int MpInterface::position() +{ + notImplemented(); + return -1; +} + +int MpInterface::length() +{ + notImplemented(); + return -1; +} + +bool MpInterface::quit() +{ + notImplemented(); + return false; +} + +bool MpInterface::hide() +{ + notImplemented(); + return false; +} + +bool MpInterface::show() +{ + notImplemented(); + return false; +} + +bool MpInterface::minimize() +{ + notImplemented(); + return false; +} + +QString MpInterface::getLocalFile() +{ + QString ret = mrl(); + if(ret.isEmpty())return ret; + if(ret.startsWith("file://",Qt::CaseInsensitive)) + { + ret.remove(0,7); + return ret; + } + return QString(); +} + +QString MpInterface::amipEval(const QString &) +{ + return QString(); +} + +#define SCAN_MP3_FILE \ + QString f = getLocalFile(); \ + if(f.isEmpty())return QString(); \ + mp3info mp3; \ + if(!scan_mp3_file(f,&mp3))return QString(); \ + QTextCodec *pCodec; \ + pCodec=mediaplayer_get_codec(); + +#define SCAN_MP3_FILE_RET_INT \ + QString f = getLocalFile(); \ + if(f.isEmpty())return -1; \ + mp3info mp3; \ + if(!scan_mp3_file(f,&mp3))return -1; + + +QString MpInterface::artist() +{ + SCAN_MP3_FILE + return pCodec->toUnicode(QByteArray(mp3.id3.artist)); +} + +QString MpInterface::title() +{ + SCAN_MP3_FILE + return pCodec->toUnicode(QByteArray(mp3.id3.title)); +} + +QString MpInterface::genre() +{ + SCAN_MP3_FILE + return pCodec->toUnicode(QByteArray(get_typegenre(mp3.id3.genre[0]))); +} + +QString MpInterface::comment() +{ + SCAN_MP3_FILE + return pCodec->toUnicode(QByteArray(mp3.id3.comment)); +} + +QString MpInterface::year() +{ + SCAN_MP3_FILE + return QString(mp3.id3.year); +} + +QString MpInterface::album() +{ + SCAN_MP3_FILE + return pCodec->toUnicode(QByteArray(mp3.id3.album)); +} + +bool MpInterface::playMrl(const QString &) +{ + notImplemented(); + return false; +} + +bool MpInterface::amipExec(const QString &) +{ + notImplemented(); + return false; +} + +bool MpInterface::setVol(kvs_int_t &) +{ + notImplemented(); + return false; +} + +int MpInterface::getVol() +{ + notImplemented(); + return -1; +} + +bool MpInterface::mute() +{ + notImplemented(); + return false; +} + +bool MpInterface::jumpTo(kvs_int_t &) +{ + notImplemented(); + return false; +} + +MpInterface::PlayerStatus MpInterface::status() +{ + notImplemented(); + return MpInterface::Unknown; +} + +int MpInterface::bitRate() +{ + SCAN_MP3_FILE_RET_INT + return header_bitrate(&(mp3.header)); +} + +int MpInterface::sampleRate() +{ + SCAN_MP3_FILE_RET_INT + return header_frequency(&(mp3.header)); +} + +int MpInterface::channels() +{ + SCAN_MP3_FILE_RET_INT + return header_channels(&(mp3.header)); +} + +int MpInterface::getPlayListPos() +{ + notImplemented(); + return -1; +} + +bool MpInterface::setPlayListPos(kvs_int_t &) +{ + notImplemented(); + return false; +} + +int MpInterface::getListLength() +{ + notImplemented(); + return -1; +} + +int MpInterface::getEqData(kvs_int_t &) +{ + notImplemented(); + return -1; +} + +bool MpInterface::setEqData(kvs_int_t &, kvs_int_t &) +{ + notImplemented(); + return false; +} + +bool MpInterface::getRepeat() +{ + notImplemented(); + return false; +} + +bool MpInterface::getShuffle() +{ + notImplemented(); + return false; +} + +bool MpInterface::setRepeat(bool &) +{ + notImplemented(); + return false; +} + +bool MpInterface::setShuffle(bool &) +{ + notImplemented(); + return false; +} + +QString MpInterface::mediaType() +{ + QString ret = mrl(); + if(ret.endsWith(".mp3",Qt::CaseInsensitive))ret = "MPEG Layer 3"; + else if(ret.endsWith(".ogg",Qt::CaseInsensitive))ret = "OGG Vorbis"; + else if(ret.endsWith(".avi",Qt::CaseInsensitive))ret = "Audio Video Interleave"; + else if(ret.endsWith(".mpeg",Qt::CaseInsensitive))ret = "MPEG Video"; + else if(ret.endsWith(".mpg",Qt::CaseInsensitive))ret = "MPEG Video"; + else if(ret.startsWith("http://",Qt::CaseInsensitive))ret = "HTTP Audio Stream"; + else ret = QString(); + return ret; +} diff --git a/src/modules/mediaplayer/MpInterface.h b/src/modules/mediaplayer/MpInterface.h new file mode 100644 index 000000000..9e205b4c9 --- /dev/null +++ b/src/modules/mediaplayer/MpInterface.h @@ -0,0 +1,238 @@ +#ifndef _MP_INTERFACE_H_ +#define _MP_INTERFACE_H_ +//============================================================================= +// +// File : MpInterface.h +// Creation date : Fri Mar 25 20:01:25 2005 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" +#include "KviQString.h" +#include "KviKvsTypes.h" + +class MpInterface +{ +public: + // don't do any initialization in the constructor + // implement lazy initialization in each function instead + MpInterface(){}; + virtual ~MpInterface(){}; +protected: + QString m_szLastError; +public: + const QString & lastError() const { return m_szLastError; }; + + // + // mandatory interface + // + + // This should attempt to detect if the player is available on the user's system + // and returning a score from 0 to 100 depending on how likely the player will work + // and how many of its functions are available. 100 means that the interface + // is absolutely sure that the player will start and play stuff. + // If bStart is true then the function is allowed to explicitly start the player, + // otherwise a startup attempt should not be made and different methods should be used. + // This function is used for auto-detection and is called twice: the first time + // with bStart set to false to determine the players that potentially could run. + // If no player returns a reasonably high value by just guessing, then + // a second loop may be attempted with the "bStart" parameter set to true. + // A level of 0 is considered total failure: in this case detect() should + // also set the last error to a descriptive string. + virtual int detect(bool bStart) = 0; + + // play previous media, return false only on communication failure + virtual bool prev() = 0; + // play next media, return false only on communication failure + virtual bool next() = 0; + // start playback now, return false only on communication failure (i.e. return true when already playing) + virtual bool play() = 0; + // stop playback now, return false only on communication failure (i.e. return true when already stopped) + virtual bool stop() = 0; + // pause playback now (do NOT toggle pause, just pause), return false only on communication failure + virtual bool pause() = 0; + + // current media related + + // currently played media: it should include AT least the title + // but may also include other information. + // this string MUST be non-empty when the player is playing something. + // If it is empty then either the player is not playing or there are + // communication errors. + virtual QString nowPlaying() = 0; + // currently played media resource locator + // file:// for local files, dvb:// for dvb media, dvd:// for dvd's + // http:// for audio streams etc... + // empty if player is not playing (or in the tragic case that the player + // can't determine the url). + virtual QString mrl() = 0; + + // optional interface + + // this should play the specified mrl + // the mrl may be (or may be not) added to the player's playlist + // the function should return false if the player doesn't support + // this function or there is a communication error + virtual bool playMrl(const QString &mrl); + // what is this ? :D + virtual bool amipExec(const QString &cmd); + virtual QString amipEval(const QString &cmd); + // this is functions to hide,show and minimize the player interface + virtual bool hide(); + virtual bool show(); + virtual bool minimize(); + // set the volume of mediaplayer (0-255) + virtual bool setVol(kvs_int_t &iVol); + // get the pvolume value(0-255) + virtual int getVol(); + //mute the volume + virtual bool mute(); + // should quit the player if it's running + // return false only on communication failure + virtual bool quit(); + // return the current player status + enum PlayerStatus { Unknown, Stopped, Playing, Paused }; + virtual MpInterface::PlayerStatus status(); + // current position in the media (msecs) + // 0 if the player isn't playing anything and -1 if unknown + virtual int position(); + // total length of the media (msecs) + // 0 if the player isn't playing anyting and -1 if unknown (e.g. a stream) + virtual int length(); + // jump to position + virtual bool jumpTo(kvs_int_t &iPos); + // interface with a default implementation for certain types of media (read for mp3) + // reimplement only if the player knows better + + // currently played media title (it's player choice if the title + // is to be derived from the media file name or from the information + // stored inside the file like the ID3 tag...) + // If the player is not playing, the returned string should be empty + virtual QString title(); + // currently played media artist's name + // If the player is not playing, the returned string should be empty + // If the player can't guess the artist it should return the string "unknown" + virtual QString artist(); + // currently plaued media genre + // If the player is not playing, the returned string should be empty + // If the player can't guess the genre it should return the string "unknown" + virtual QString genre(); + // currently played media comment. + // Empty string if the player isn't playing anything or there is no comment + virtual QString comment(); + // currently played media year + // Empty string if the player isn't playing anything or the year is unknown + virtual QString year(); + // currently played media album + // Empty string if the player isn't playing anything + // If the player can't guess the album/collection then this string should be "unknown" + virtual QString album(); + // bit rate in bits/sec, 0 if unknown + virtual int bitRate(); + // sample rate in samples/sec (Hz), 0 if unknown + virtual int sampleRate(); + // number of channels + virtual int channels(); + // frequency + // the type of the media (MPEG Layer 3, MPEG Layer 4, OGG Vorbis, AVI Stream etc..) + virtual QString mediaType(); + // get the position in the playlist + virtual int getPlayListPos(); + // set the position in the playlist + virtual bool setPlayListPos(kvs_int_t &iPos); + // return the list's length + virtual int getListLength(); + // return the Eq(number) value + virtual int getEqData(kvs_int_t &i_val); + // set the Eq(iPos) to Eq(iVal) value + virtual bool setEqData(kvs_int_t &iPos, kvs_int_t &iVal); + // get the Repeat bool value + virtual bool getRepeat(); + // get the shuffle bool value + virtual bool getShuffle(); + // set the Repeat bool value + virtual bool setRepeat(bool &bVal); + // set the shuffle bool value + virtual bool setShuffle(bool &bVal); + void setLastError(const QString &szLastError){ m_szLastError = szLastError; }; +protected: + void notImplemented(); + QString getLocalFile(); +}; + + +class MpInterfaceDescriptor +{ +public: + MpInterfaceDescriptor(){}; + virtual ~MpInterfaceDescriptor(){}; +public: + virtual const QString & name() = 0; + virtual const QString & description() = 0; + virtual MpInterface * instance() = 0; +}; + + +#define MP_DECLARE_DESCRIPTOR(_interfaceclass) \ + class _interfaceclass ## Descriptor : public MpInterfaceDescriptor \ + { \ + public: \ + _interfaceclass ## Descriptor(); \ + virtual ~_interfaceclass ## Descriptor(); \ + protected: \ + _interfaceclass * m_pInstance; \ + QString m_szName; \ + QString m_szDescription; \ + public: \ + virtual const QString & name(); \ + virtual const QString & description(); \ + virtual MpInterface * instance(); \ + }; + +#define MP_IMPLEMENT_DESCRIPTOR(_interfaceclass,_name,_description) \ + _interfaceclass ## Descriptor::_interfaceclass ## Descriptor() \ + : MpInterfaceDescriptor() \ + { \ + m_pInstance = 0; \ + m_szName = _name; \ + m_szDescription = _description; \ + } \ + _interfaceclass ## Descriptor::~_interfaceclass ## Descriptor() \ + { \ + if(m_pInstance)delete m_pInstance; \ + } \ + const QString & _interfaceclass ## Descriptor::name() \ + { \ + return m_szName; \ + } \ + const QString & _interfaceclass ## Descriptor::description() \ + { \ + return m_szDescription; \ + } \ + MpInterface * _interfaceclass ## Descriptor::instance() \ + { \ + if(!m_pInstance)m_pInstance = new _interfaceclass(); \ + return m_pInstance; \ + } + +#define MP_CREATE_DESCRIPTOR(_interfaceclass) \ + new _interfaceclass ## Descriptor() + +#endif //!_MP_INTERFACE_H_ diff --git a/src/modules/mediaplayer/MpMp3.cpp b/src/modules/mediaplayer/MpMp3.cpp new file mode 100644 index 000000000..9f3e68cbe --- /dev/null +++ b/src/modules/mediaplayer/MpMp3.cpp @@ -0,0 +1,458 @@ +//============================================================================= +// +// File : MpMp3.cpp +// Creation date : Fri Mar 25 20:01:25 2005 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This file is based on the mp3tech.c. It is released under the original +// license and the original copyright notice follows. +// +// mp3tech.c +// +// Copyright (C) 2000 Cedric Tefft +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// This file is based in part on: +// +// * MP3Info 0.5 by Ricardo Cerqueira +// * MP3Stat 0.9 by Ed Sweetman and +// Johannes Overmann +// +// There has been also a remarkable work by Cristopher Tieckle (Crissi) +// +//============================================================================= + +#include "MpMp3.h" +#include "KviOptions.h" + +#include +#include + +#define MAXGENRE 147 +#define GENREROWS 50 + +/* + The Information is stored in the last 128 bytes of an MP3. The Tag + has got the following fields, and the offsets given here, are from + 0-127. + + Field Length Offsets + Tag 3 0-2 + Songname 30 3-32 + Artist 30 33-62 + Album 30 63-92 + Year 4 93-96 + Comment 30 97-126 + Genre 1 127 + + + The string-fields contain ASCII-data, coded in ISO-Latin 1 codepage. + Strings which are smaller than the field length are padded with zero- + bytes. + + Tag: The tag is valid if this field contains the string "TAG". This + has to be uppercase! + + Songname: This field contains the title of the MP3 (string as + above). + + Artist: This field contains the artist of the MP3 (string as above). + + Album: this field contains the album where the MP3 comes from + (string as above). + + Year: this field contains the year when this song has originally + been released (string as above). + + Comment: this field contains a comment for the MP3 (string as + above). Revision to this field has been made in ID3v1.1. See + A.4. + + Genre: this byte contains the offset of a genre in a predefined + list the byte is treated as an unsigned byte. The offset is + starting from 0. See A.3. +*/ + + +const char *typegenre [MAXGENRE+2] = +{ + "Blues","Classic Rock","Country","Dance","Disco","Funk","Grunge", + "Hip-Hop","Jazz","Metal","New Age","Oldies","Other","Pop","R&B", + "Rap","Reggae","Rock","Techno","Industrial","Alternative","Ska", + "Death Metal","Pranks","Soundtrack","Euro-Techno","Ambient", + "Trip-Hop","Vocal","Jazz+Funk","Fusion","Trance","Classical", + "Instrumental","Acid","House","Game","Sound Clip","Gospel","Noise", + "Alt. Rock","Bass","Soul","Punk","Space","Meditative", + "Instrumental Pop","Instrumental Rock","Ethnic","Gothic", + "Darkwave","Techno-Industrial","Electronic","Pop-Folk","Eurodance", + "Dream","Southern Rock","Comedy","Cult","Gangsta Rap","Top 40", + "Christian Rap","Pop/Funk","Jungle","Native American","Cabaret", + "New Wave","Psychedelic","Rave","Showtunes","Trailer","Lo-Fi", + "Tribal","Acid Punk","Acid Jazz","Polka","Retro","Musical", + "Rock & Roll","Hard Rock","Folk","Folk/Rock","National Folk", + "Swing","Fast-Fusion","Bebob","Latin","Revival","Celtic", + "Bluegrass","Avantgarde","Gothic Rock","Progressive Rock", + "Psychedelic Rock","Symphonic Rock","Slow Rock","Big Band", + "Chorus","Easy Listening","Acoustic","Humour","Speech","Chanson", + "Opera","Chamber Music","Sonata","Symphony","Booty Bass","Primus", + "Porn Groove","Satire","Slow Jam","Club","Tango","Samba", + "Folklore","Ballad","Power Ballad","Rhythmic Soul","Freestyle", + "Duet","Punk Rock","Drum Solo","A Cappella","Euro-House", + "Dance Hall","Goa","Drum & Bass","Club-House","Hardcore","Terror", + "Indie","BritPop","Negerpunk","Polsk Punk","Beat", + "Christian Gangsta Rap","Heavy Metal","Black Metal","Crossover", + "Contemporary Christian","Christian Rock","Merengue","Salsa", + "Thrash Metal","Anime","JPop","Synthpop","" +}; + +const char * get_typegenre(int idx) +{ + if(idx > MAXGENRE)return typegenre[12]; + return typegenre[idx]; +} + +int galphagenreindex[MAXGENRE+2] = +{ + 148,123,74,73,34,99,40,20,26,145,90, + 116,41,135,85,96,138,89,0,107,132,65,88, + 104,102,97,136,61,141,1,32,128,112,57,140, + 2,139,58,125,3,50,22,4,55,127,122,120, + 98,52,48,124,25,54,84,81,115,80,119,5, + 30,36,59,126,38,91,49,6,79,129,137,7, + 35,100,131,19,46,47,33,146,29,8,63,86, + 71,45,142,9,77,82,64,133,10,66,39,11, + 103,12,75,134,53,62,13,109,117,23,108,92, + 93,67,121,43,14,15,68,16,76,87,118,78, + 17,143,114,110,69,21,111,95,105,42,37,24, + 56,44,101,83,94,106,147,113,51,18,130,144, + 60,70,31,72,27,28 +}; + +int *alphagenreindex=&(galphagenreindex[1]); + + +int layer_tab[4]= {0, 3, 2, 1}; + +int frequencies[3][4] = +{ + {22050,24000,16000,50000}, /* MPEG 2.0 */ + {44100,48000,32000,50000}, /* MPEG 1.0 */ + {11025,12000,8000,50000} /* MPEG 2.5 */ +}; + +int bitrate[2][3][14] = +{ + { /* MPEG 2.0 */ + {32,48,56,64,80,96,112,128,144,160,176,192,224,256}, /* layer 1 */ + {8,16,24,32,40,48,56,64,80,96,112,128,144,160}, /* layer 2 */ + {8,16,24,32,40,48,56,64,80,96,112,128,144,160} /* layer 3 */ + }, + { /* MPEG 1.0 */ + {32,64,96,128,160,192,224,256,288,320,352,384,416,448}, /* layer 1 */ + {32,48,56,64,80,96,112,128,160,192,224,256,320,384}, /* layer 2 */ + {32,40,48,56,64,80,96,112,128,160,192,224,256,320} /* layer 3 */ + } +}; + +int frame_size_index[] = {24000, 72000, 72000}; + +const char *mode_text[] = +{ + "Stereo", "Joint Stereo", "Dual Channel", "Mono" +}; + +const char *emphasis_text[] = +{ + "None", "50/15 Microseconds", "Reserved", "CCITT J 17" +}; + +void resetmp3infoStruct(mp3info *i) +{ + i->file=0; + i->datasize=0; + i->header_isvalid=0; + memset(&i->header,0,sizeof(i->header)); + i->id3_isvalid=0; + memset(&i->id3,0,sizeof(i->id3)); + i->vbr=0; + i->vbr_average=0; + i->seconds=0; + i->frames=0; + i->badframes=0; +} + +int get_mp3_info(mp3info *mp3) +{ +// mp3header header; + + QFile fi(mp3->filename); + mp3->datasize=fi.size();//filestat.st_size; + + get_id3(mp3); + + if(get_first_header(mp3,0L)) + { + int bitrate,counter=0; + int data_start=ftell(mp3->file); + int lastrate=15-mp3->header.bitrate; + while((counter < NUM_SAMPLES) && lastrate) + { + int sample_pos=(counter*(mp3->datasize/NUM_SAMPLES+1))+data_start; + if(get_first_header(mp3,sample_pos)) + { + bitrate=15-mp3->header.bitrate; + } else { + bitrate=-1; + } + + if(bitrate != lastrate) + { + mp3->vbr=1; + } + lastrate=bitrate; + counter++; + + } + mp3->frames=(mp3->datasize-data_start)/(frame_length(&mp3->header)); + mp3->seconds = (int)((float)(frame_length(&mp3->header)*mp3->frames)/ + (float)(header_bitrate(&mp3->header)*125)+0.5); + mp3->vbr_average = (float)header_bitrate(&mp3->header); + } + + return 0; +} + +int get_first_header(mp3info *mp3, long startpos) +{ + int k, l=0,c; + mp3header h, h2; + long valid_start=0; + + fseek(mp3->file,startpos,SEEK_SET); + while(1) + { + while((c=fgetc(mp3->file)) != 255 && (c != EOF)) {} + if(c == 255) + { + ungetc(c,mp3->file); + valid_start=ftell(mp3->file); + if((l=get_header(mp3->file,&h))) + { + fseek(mp3->file,l-FRAME_HEADER_SIZE,SEEK_CUR); + for(k=1; (k < MIN_CONSEC_GOOD_FRAMES) && (mp3->datasize-ftell(mp3->file) >= FRAME_HEADER_SIZE); k++) + { + if(!(l=get_header(mp3->file,&h2))) break; + if(!sameConstant(&h,&h2)) break; + fseek(mp3->file,l-FRAME_HEADER_SIZE,SEEK_CUR); + } + if(k == MIN_CONSEC_GOOD_FRAMES) + { + fseek(mp3->file,valid_start,SEEK_SET); + memcpy(&(mp3->header), &h2, sizeof(mp3header)); + mp3->header_isvalid = 1; + return 1; + } + } + } else { + return 0; + } + } + return 0; +} + + +// Get next MP3 frame header. +// Return codes: +// positive value = Frame Length of this header +// 0 = No, we did not retrieve a valid frame header + +int get_header(FILE *file,mp3header *header) +{ + unsigned char buffer[FRAME_HEADER_SIZE]; + int fl; + + if(fread(&buffer,FRAME_HEADER_SIZE,1,file)<1) + { + header->sync=0; + return 0; + } + header->sync=(((int)buffer[0]<<4) | ((int)(buffer[1]&0xE0)>>4)); + if(buffer[1] & 0x10) header->version=(buffer[1] >> 3) & 1; + else header->version=2; + header->layer=(buffer[1] >> 1) & 3; + if((header->sync != 0xFFE) || (header->layer != 1)) + { + header->sync=0; + return 0; + } + header->crc=buffer[1] & 1; + header->bitrate=(buffer[2] >> 4) & 0x0F; + header->freq=(buffer[2] >> 2) & 0x3; + header->padding=(buffer[2] >>1) & 0x1; + header->extension=(buffer[2]) & 0x1; + header->mode=(buffer[3] >> 6) & 0x3; + header->mode_extension=(buffer[3] >> 4) & 0x3; + header->copyright=(buffer[3] >> 3) & 0x1; + header->original=(buffer[3] >> 2) & 0x1; + header->emphasis=(buffer[3]) & 0x3; + + return ((fl=frame_length(header)) >= MIN_FRAME_SIZE ? fl : 0); +} + +int frame_length(mp3header *header) +{ + return header->sync == 0xFFE ? + (frame_size_index[3-header->layer]*((header->version&1)+1)* + header_bitrate(header)/header_frequency(header))+ + header->padding : 1; +} + +int header_layer(mp3header *h) +{ + return layer_tab[h->layer]; +} + +int header_bitrate(mp3header *h) +{ + if(h->bitrate > 0) + return bitrate[h->version & 1][3-h->layer][h->bitrate-1]; + else + return -1; // unknown +} + +int header_frequency(mp3header *h) +{ + return frequencies[h->version][h->freq]; +} + +const char *header_emphasis(mp3header *h) +{ + return emphasis_text[h->emphasis]; +} + +const char *header_mode(mp3header *h) +{ + return mode_text[h->mode]; +} + +int header_channels(mp3header * h) +{ + return h->mode == 3 ? 1 : 2; +} + +int header_crc(mp3header *h) +{ + return (!h->crc); +} + +int sameConstant(mp3header *h1, mp3header *h2) +{ + if((*(uint*)h1) == (*(uint*)h2)) return 1; + + if((h1->version == h2->version ) && + (h1->layer == h2->layer ) && + (h1->crc == h2->crc ) && + (h1->freq == h2->freq ) && + (h1->mode == h2->mode ) && + (h1->copyright == h2->copyright ) && + (h1->original == h2->original ) && + (h1->emphasis == h2->emphasis )) + return 1; + else return 0; +} + +int get_id3(mp3info *mp3) +{ + // this will read ID3v1 tags + int retcode=0; + char fbuf[4]; + + if(mp3->datasize >= 128) + { + if(fseek(mp3->file, -128, SEEK_END )) + { + retcode |= 4; + } else { + size_t dummy = fread(fbuf,1,3,mp3->file); fbuf[3] = '\0'; + mp3->id3.genre[0]=255; + + if(!strcmp((const char *)"TAG",(const char *)fbuf)) + { + mp3->id3_isvalid=1; + mp3->datasize -= 128; + fseek(mp3->file, -125, SEEK_END); + dummy = fread(mp3->id3.title,1,30,mp3->file); mp3->id3.title[30] = '\0'; + dummy = fread(mp3->id3.artist,1,30,mp3->file); mp3->id3.artist[30] = '\0'; + dummy = fread(mp3->id3.album,1,30,mp3->file); mp3->id3.album[30] = '\0'; + dummy = fread(mp3->id3.year,1,4,mp3->file); mp3->id3.year[4] = '\0'; + dummy = fread(mp3->id3.comment,1,30,mp3->file); mp3->id3.comment[30] = '\0'; + if(mp3->id3.comment[28] == '\0') + { + mp3->id3.track[0] = mp3->id3.comment[29]; + } + dummy = fread(mp3->id3.genre,1,1,mp3->file); + unpad(mp3->id3.title); + unpad(mp3->id3.artist); + unpad(mp3->id3.album); + unpad(mp3->id3.year); + unpad(mp3->id3.comment); + } + } + } + return retcode; +} + +char *pad(char *string, int length) +{ + int l; + + l=strlen(string); + while(lfilename = "text"; + i->file = fopen(QTextCodec::codecForLocale()->fromUnicode(i->filename).data(),"rb"); + if(!i->file)return false; + + get_mp3_info(i); + + fclose(i->file); + + return (i->id3_isvalid); +} diff --git a/src/modules/mediaplayer/MpMp3.h b/src/modules/mediaplayer/MpMp3.h new file mode 100644 index 000000000..b50c3e953 --- /dev/null +++ b/src/modules/mediaplayer/MpMp3.h @@ -0,0 +1,137 @@ +//============================================================================= +// +// File : MpMp3.h +// Creation date : Fri Mar 25 20:01:25 2005 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This file is based on the mp3tech.h. It is released under the original +// license and the original copyright notice follows. +// +// mp3tech.hCO +// +// Copyright (C) 2000 Cedric Tefft +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// This file is based in part on: +// +// * MP3Info 0.5 by Ricardo Cerqueira +// * MP3Stat 0.9 by Ed Sweetman and +// Johannes Overmann +// +// There has been also a remarkable work by Cristopher Tieckle (Crissi) +// +//============================================================================= + +// MIN_CONSEC_GOOD_FRAMES defines how many consecutive valid MP3 frames +// we need to see before we decide we are looking at a real MP3 file +#define MIN_CONSEC_GOOD_FRAMES 4 +#define FRAME_HEADER_SIZE 4 +#define MIN_FRAME_SIZE 21 +#define NUM_SAMPLES 4 +#define TEXT_FIELD_LEN 30 +#define INT_FIELD_LEN 4 + + +#include "kvi_settings.h" + +#include +#include +#include + +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + #include +#else + #include + #include + #include + #include +#endif + + +enum VBR_REPORT { VBR_VARIABLE, VBR_AVERAGE, VBR_MEDIAN }; + +typedef struct { + unsigned int sync; + unsigned int version; + unsigned int layer; + unsigned int crc; + unsigned int bitrate; + unsigned int freq; + unsigned int padding; + unsigned int extension; + unsigned int mode; + unsigned int mode_extension; + unsigned int copyright; + unsigned int original; + unsigned int emphasis; +} mp3header; + +typedef struct { + char title[31]; + char artist[31]; + char album[31]; + char year[5]; + char comment[31]; + unsigned char track[1]; + unsigned char genre[1]; +} id3tag; + +typedef struct { + QString filename; + FILE *file; + unsigned int datasize; + int header_isvalid; + mp3header header; + int id3_isvalid; + id3tag id3; + int vbr; + float vbr_average; + int seconds; + int frames; + int badframes; +} mp3info; + +// mode field: +// 00 - Stereo +// 01 - Joint stereo (Stereo) +// 10 - Dual channel (2 mono channels) +// 11 - Single channel (Mono) + +bool scan_mp3_file(QString& szFileName,mp3info * i); + +void resetmp3infoStruct(mp3info *i); + +int header_channels(mp3header *h); +int header_frequency(mp3header *h); +const char *header_emphasis(mp3header *h); +const char *header_mode(mp3header *h); +int header_layer(mp3header *h); +int header_bitrate(mp3header *h); +double header_version(mp3header *h); +int header_crc(mp3header *h); +int get_header(FILE *file,mp3header *header); +int frame_length(mp3header *header); +int sameConstant(mp3header *h1, mp3header *h2); +int get_mp3_info(mp3info *mp3); +int get_id3(mp3info *mp3); +char *pad(char *string, int length); +char *unpad(char *string); +int get_first_header(mp3info *mp3,long startpos); +//void tagedit_curs(char *filename, int filenum, int fileoutof, id3tag *tag); +const char * get_typegenre(int idx); + diff --git a/src/modules/mediaplayer/MpMprisInterface.cpp b/src/modules/mediaplayer/MpMprisInterface.cpp new file mode 100644 index 000000000..560d03c93 --- /dev/null +++ b/src/modules/mediaplayer/MpMprisInterface.cpp @@ -0,0 +1,579 @@ +//============================================================================= +// +// File : MpMprisInterface.cpp +// Creation date : Thu 06 Dec 2007 14:20:02 by Tomasz MoÅ„ +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2007-2009 Tomasz MoÅ„ +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "MpMprisInterface.h" +#if (defined(COMPILE_DBUS_SUPPORT) && !defined(COMPILE_ON_WINDOWS) && !defined(COMPILE_ON_MAC) && !defined(COMPILE_ON_MINGW)) +#include "KviLocale.h" + +/* + according to MPRIS 1.0, GetStatus returns struct of 4 integers. + + First integer: 0 = Playing, 1 = Paused, 2 = Stopped. + Second interger: 0 = Playing linearly, 1 = Playing randomly. + Third integer: 0 = Go to the next element once the current has finished playing, 1 = Repeat the current element + Fourth integer: 0 = Stop playing once the last element has been played, 1 = Never give up playing +*/ + +struct MPRISPlayerStatus +{ + int Play; + int Random; + int RepeatCurrent; + int RepeatPlaylist; +}; +Q_DECLARE_METATYPE( MPRISPlayerStatus ) + +QDBusArgument &operator<<(QDBusArgument &argument, const MPRISPlayerStatus &status) +{ + argument.beginStructure(); + argument << status.Play << status.Random << status.RepeatCurrent << status.RepeatPlaylist; + argument.endStructure(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, MPRISPlayerStatus &status) +{ + argument.beginStructure(); + argument >> status.Play >> status.Random >> status.RepeatCurrent >> status.RepeatPlaylist; + argument.endStructure(); + return argument; +} + +MpMprisInterface::MpMprisInterface() +: MpInterface() +{ + qDBusRegisterMetaType(); +} + +MpMprisInterface::~MpMprisInterface() +{ +} + +int MpMprisInterface::detect(bool) +{ + QDBusReply reply = QDBusConnection::sessionBus().interface()->registeredServiceNames(); + if (!reply.isValid()) /* something fishy with dbus, it won't work */ + return 0; + + foreach (QString name, reply.value()) + if (name == m_szServiceName) /* player is running */ + return 100; + + return 1; /* dbus works, player may be closed */ +} + +#define MPRIS_SIMPLE_CALL(__path, __action) \ + QDBusInterface dbus_iface(m_szServiceName, __path, \ + "org.freedesktop.MediaPlayer", QDBusConnection::sessionBus()); \ + QDBusMessage reply = dbus_iface.call(QDBus::Block, __action); \ + if (reply.type() == QDBusMessage::ErrorMessage) { \ + QDBusError err = reply; \ + qDebug("Error: %s\n%s\n", qPrintable(err.name()), qPrintable(err.message())); \ + return FALSE; \ + } \ + return TRUE; + +bool MpMprisInterface::prev() +{ + MPRIS_SIMPLE_CALL("/Player", "Prev") +} + +bool MpMprisInterface::next() +{ + MPRIS_SIMPLE_CALL("/Player", "Next") +} + +bool MpMprisInterface::play() +{ + MPRIS_SIMPLE_CALL("/Player", "Play") +} + +bool MpMprisInterface::stop() +{ + MPRIS_SIMPLE_CALL("/Player", "Stop") +} + +bool MpMprisInterface::pause() +{ + MPRIS_SIMPLE_CALL("/Player", "Pause") +} + +bool MpMprisInterface::quit() +{ + MPRIS_SIMPLE_CALL("/", "Quit") +} + +#define MPRIS_CALL_METHOD(__method, __return_if_fail) \ + QDBusInterface dbus_iface(m_szServiceName, "/Player", \ + "org.freedesktop.MediaPlayer", QDBusConnection::sessionBus()); \ + QDBusMessage reply = dbus_iface.call(QDBus::Block, __method); \ + if (reply.type() == QDBusMessage::ErrorMessage) { \ + QDBusError err = reply; \ + qDebug("Error: %s\n%s\n", qPrintable(err.name()), qPrintable(err.message())); \ + return __return_if_fail; \ + } + +#define MPRIS_GET_METADATA_FIELD(__field, __return_type, __return_if_fail) \ + if (this->status() != MpInterface::Playing) \ + return __return_if_fail; \ + MPRIS_CALL_METHOD("GetMetadata", __return_if_fail) \ + foreach (QVariant v, reply.arguments()) { \ + QDBusArgument arg = qvariant_cast(v); \ + QVariant v = qdbus_cast(arg); \ + if (v.userType() == QVariant::Map) { \ + const QVariantMap map = v.toMap(); \ + QVariantMap::ConstIterator it = map.find(__field); \ + if (it != map.end() && it.key() == __field) { \ + return it.value().value< __return_type >(); \ + } \ + } \ + } \ + return __return_if_fail; + +#define MPRIS_CALL_METHOD_WITH_ARG(__method, __arg, __return_if_fail) \ + QDBusInterface dbus_iface(m_szServiceName, "/Player", \ + "org.freedesktop.MediaPlayer", QDBusConnection::sessionBus()); \ + QDBusMessage reply = dbus_iface.call(QDBus::Block, __method, __arg); \ + if (reply.type() == QDBusMessage::ErrorMessage) { \ + QDBusError err = reply; \ + qDebug("Error: %s\n%s\n", qPrintable(err.name()), qPrintable(err.message())); \ + return __return_if_fail; \ + } + +MpInterface::PlayerStatus MpMprisInterface::status() +{ + MPRIS_CALL_METHOD("GetStatus", MpInterface::Unknown) + + MPRISPlayerStatus status; + + if(reply.arguments().isEmpty()) + return MpInterface::Unknown; + + status = qdbus_cast(reply.arguments().first()); + + switch (status.Play) { + case 0: return MpInterface::Playing; + case 1: return MpInterface::Paused; + case 2: return MpInterface::Stopped; + default: return MpInterface::Unknown; + } +} + +QString MpMprisInterface::nowPlaying() +{ + if (this->status() != MpInterface::Playing) + return ""; + + MPRIS_CALL_METHOD("GetMetadata", "") + + QString artist; + QString title; + foreach (QVariant v, reply.arguments()) { + QDBusArgument arg = qvariant_cast(v); + QVariant v = qdbus_cast(arg); + if (v.userType() == QVariant::Map) { + const QVariantMap map = v.toMap(); + QVariantMap::ConstIterator it = map.constBegin(); + for ( ; it != map.constEnd(); ++it) { /* maybe do some configureable formatting */ + if (it.key() == "artist") + artist = it.value().toString(); + else if (it.key() == "title") + title = it.value().toString(); + } + } + } + if (artist.length() && title.length()) + return artist + " - " + title; + else + return ""; +} + +QString MpMprisInterface::mrl() +{ + MPRIS_CALL_METHOD("GetMetadata", "") + + foreach (QVariant v, reply.arguments()) { + QDBusArgument arg = qvariant_cast(v); + QVariant v = qdbus_cast(arg); + if (v.userType() == QVariant::Map) { + const QVariantMap map = v.toMap(); + QVariantMap::ConstIterator it = map.find("location"); + if (it != map.end() && it.key() == "location") { + return it.value().toString(); + } + } + } + return ""; +} + +QString MpMprisInterface::title() +{ + MPRIS_GET_METADATA_FIELD("title", QString, "") +} + +QString MpMprisInterface::artist() +{ + MPRIS_GET_METADATA_FIELD("artist", QString, "") +} + +QString MpMprisInterface::genre() +{ + MPRIS_GET_METADATA_FIELD("genre", QString, "") +} + +QString MpMprisInterface::comment() +{ + MPRIS_GET_METADATA_FIELD("comment", QString, "") +} + +QString MpMprisInterface::year() +{ + MPRIS_GET_METADATA_FIELD("year", QString, "") +} + +QString MpMprisInterface::album() +{ + MPRIS_GET_METADATA_FIELD("album", QString, "") +} + +int MpMprisInterface::bitRate() +{ + MPRIS_GET_METADATA_FIELD("audio-bitrate", int, -1) +} + +int MpMprisInterface::sampleRate() +{ + MPRIS_GET_METADATA_FIELD("audio-samplerate", int, -1) +} + +bool MpMprisInterface::setVol(kvs_int_t &iVol) +{ + MPRIS_CALL_METHOD_WITH_ARG("VolumeSet", QVariant((int)(100*iVol/255)), false); + return true; +} + +int MpMprisInterface::getVol() +{ + MPRIS_CALL_METHOD("VolumeGet", -1) + + int iVol = reply.arguments().first().toInt(); + return iVol * 255 /100; +} + +int MpMprisInterface::position() +{ + MPRIS_CALL_METHOD("PositionGet", -1) + return reply.arguments().first().toInt(); +} + +int MpMprisInterface::length() +{ + MPRIS_CALL_METHOD("GetMetadata", -1) + + foreach (QVariant v, reply.arguments()) { + QDBusArgument arg = qvariant_cast(v); + QVariant v = qdbus_cast(arg); + if (v.userType() == QVariant::Map) { + const QVariantMap map = v.toMap(); + QVariantMap::ConstIterator it = map.constBegin(); + for ( ; it != map.constEnd(); ++it) { + if (it.key() == "mtime") + return it.value().toInt(); + } + } + } + return -1; +} + +bool MpMprisInterface::jumpTo(kvs_int_t &iPos) +{ + MPRIS_CALL_METHOD_WITH_ARG("PositionSet", QVariant((int)iPos), false) + return true; +} + +/* audacious interface */ +MP_IMPLEMENT_DESCRIPTOR( + MpAudaciousInterface, + "audacious", + __tr2qs_ctx( + "An interface to the popular audacious media player.\n" \ + "Download it from http://audacious-media-player.org\n" + , + "mediaplayer" + ) +) + +MpAudaciousInterface::MpAudaciousInterface() +: MpMprisInterface() +{ + m_szServiceName = "org.mpris.audacious"; +} + +int MpAudaciousInterface::getPlayListPos() +{ + QDBusInterface dbus_iface("org.mpris.audacious", "/org/atheme/audacious", + "org.atheme.audacious", QDBusConnection::sessionBus()); + QDBusReply pos = dbus_iface.call(QDBus::Block, "Position"); + return pos; +} + + +bool MpAudaciousInterface::quit() +{ + if (MpMprisInterface::quit()) + return TRUE; + + /* compability with older versions */ + MPRIS_SIMPLE_CALL("/Player", "Quit") +} + +QString MpAudaciousInterface::mrl() +{ + MPRIS_CALL_METHOD("GetMetadata", "") + + foreach (QVariant v, reply.arguments()) { + QDBusArgument arg = qvariant_cast(v); + QVariant v = qdbus_cast(arg); + if (v.userType() == QVariant::Map) { + const QVariantMap map = v.toMap(); + QVariantMap::ConstIterator it = map.find("location"); + if (it != map.end() && it.key() == "location") { + return it.value().toString(); + } + /* Some audacious versions send URI instead of location */ + it = map.find("URI"); + if (it != map.end() && it.key() == "URI") { + return it.value().toString(); + } + } + } + return ""; +} + +MpInterface::PlayerStatus MpAudaciousInterface::status() +{ + MpInterface::PlayerStatus status; + status = MpMprisInterface::status(); + if (status != MpInterface::Unknown) + return status; + + /* compability with older versions */ + QDBusInterface dbus_iface(m_szServiceName, "/Player", + "org.freedesktop.MediaPlayer", QDBusConnection::sessionBus()); + if (!dbus_iface.isValid()) + return MpInterface::Unknown; + + QDBusMessage reply = dbus_iface.call(QDBus::Block, "GetStatus"); + + switch (reply.arguments().first().toInt()) { + case 0: return MpInterface::Playing; + case 1: return MpInterface::Paused; + case 2: return MpInterface::Stopped; + default: return MpInterface::Unknown; + } +} + +int MpAudaciousInterface::length() +{ + int length = MpMprisInterface::length(); + if (length != -1) + return length; + + /* compability with older versions */ + MPRIS_CALL_METHOD("GetMetadata", -1) + + foreach (QVariant v, reply.arguments()) { + QDBusArgument arg = qvariant_cast(v); + QVariant v = qdbus_cast(arg); + if (v.userType() == QVariant::Map) { + const QVariantMap map = v.toMap(); + QVariantMap::ConstIterator it = map.constBegin(); + for ( ; it != map.constEnd(); ++it) { + if (it.key() == "length") + return it.value().toInt(); + } + } + } + return -1; +} + +#define AUDACIOUS_GET_TUPLE_FIELD(__field) \ + if (this->status() != MpInterface::Playing) \ + return ""; \ + QDBusInterface dbus_iface("org.mpris.audacious", "/org/atheme/audacious", \ + "org.atheme.audacious", QDBusConnection::sessionBus()); \ + QList args; \ + args << (uint)this->getPlayListPos() << QString(__field); \ + QDBusReply reply = dbus_iface.callWithArgumentList(QDBus::Block, "SongTuple", args); \ + return reply.value().variant().toString(); \ + +QString MpAudaciousInterface::year() +{ + AUDACIOUS_GET_TUPLE_FIELD("year") +} + +QString MpAudaciousInterface::mediaType() +{ + AUDACIOUS_GET_TUPLE_FIELD("codec") +} + +/* BMPx interface */ +MP_IMPLEMENT_DESCRIPTOR( + MpBmpxInterface, + "bmpx", + __tr2qs_ctx( + "An interface to BMPx.\n" \ + "Download it from http://sourceforge.net/projects/beepmp\n" + , + "mediaplayer" + ) +) + +MpBmpxInterface::MpBmpxInterface() +: MpMprisInterface() +{ + m_szServiceName = "org.mpris.bmp"; +} + +/* BMPx doesn't provide GetStatus method, always assume Playing status */ +MpInterface::PlayerStatus MpBmpxInterface::status() +{ + return MpInterface::Playing; +} + +/* Amarok2 interface */ +MP_IMPLEMENT_DESCRIPTOR( + MpAmarok2Interface, + "amarok2", + __tr2qs_ctx( + "An interface to Amarok2.\n" \ + "Download it from http://amarok.kde.org\n" + , + "mediaplayer" + ) +) + +MpAmarok2Interface::MpAmarok2Interface() +: MpMprisInterface() +{ + m_szServiceName = "org.mpris.amarok"; +} + +/* Qmmp interface */ +MP_IMPLEMENT_DESCRIPTOR( + MpQmmpInterface, + "Qmmp", + __tr2qs_ctx( + "An interface to Qmmp.\n" \ + "Download it from http://qmmp.ylsoftware.com\n" + , + "mediaplayer" + ) +) + +MpQmmpInterface::MpQmmpInterface() +: MpMprisInterface() +{ + m_szServiceName = "org.mpris.qmmp"; +} + +/* xmms2 interface */ +MP_IMPLEMENT_DESCRIPTOR( + MpXmms2Interface, + "xmms2", + __tr2qs_ctx( + "An interface to the Xmms2 media player.\n" \ + "Download it from http://xmms2.org\n", + "mediaplayer" + ) +) + +MpXmms2Interface::MpXmms2Interface() +: MpMprisInterface() +{ + m_szServiceName = "org.mpris.xmms2"; +} + +/* mozilla songbird interface */ +MP_IMPLEMENT_DESCRIPTOR( + MpSongbirdInterface, + "songbird", + __tr2qs_ctx( + "An interface to the Mozilla Songbird media player.\n" \ + "Download it from http://www.getsongbird.com.\n" \ + "To use it you have to install also the MPRIS addon " \ + "available at http://addons.songbirdnest.com/addon/1626.\n", + "mediaplayer" + ) +) + +MpSongbirdInterface::MpSongbirdInterface() +: MpMprisInterface() +{ + m_szServiceName = "org.mpris.songbird"; +} + +MpInterface::PlayerStatus MpSongbirdInterface::status() +{ + return MpInterface::Playing; +} + +/* Totem interface */ +MP_IMPLEMENT_DESCRIPTOR( + MpTotemInterface, + "totem", + __tr2qs_ctx( + "An interface to Totem.\n" \ + "Download it from http://projects.gnome.org/totem/\n" + , + "mediaplayer" + ) +) + +MpTotemInterface::MpTotemInterface() +: MpMprisInterface() +{ + m_szServiceName = "org.mpris.Totem"; +} + +/* Vlc interface */ +MP_IMPLEMENT_DESCRIPTOR( + MpVlcInterface, + "vlc", + __tr2qs_ctx( + "An interface to Vlc.\n" \ + "Download it from http://www.videolan.org/\n" \ + "You need to manually enable the DBus control\n" \ + "interface in the Vlc preferences\n" \ + , + "mediaplayer" + ) +) + +MpVlcInterface::MpVlcInterface() +: MpMprisInterface() +{ + m_szServiceName = "org.mpris.vlc"; +} +#endif //COMPILE_ON_WINDOWS diff --git a/src/modules/mediaplayer/MpMprisInterface.h b/src/modules/mediaplayer/MpMprisInterface.h new file mode 100644 index 000000000..51767390c --- /dev/null +++ b/src/modules/mediaplayer/MpMprisInterface.h @@ -0,0 +1,135 @@ +#ifndef _MP_AUDACIOUSINTERFACE_H_ +#define _MP_AUDACIOUSINTERFACE_H_ +//============================================================================= +// +// File : MpMprisInterface.h +// Creation date : Thu 06 Dec 2007 14:20:02 by Tomasz MoÅ„ +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2007-2009 Tomasz MoÅ„ +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "MpInterface.h" + +#include "kvi_settings.h" + +#if (defined(COMPILE_DBUS_SUPPORT) && !defined(COMPILE_ON_WINDOWS) && !defined(COMPILE_ON_MAC) && !defined(COMPILE_ON_MINGW)) + #include + + class MpMprisInterface : public MpInterface + { + public: + MpMprisInterface(); + virtual ~MpMprisInterface(); + public: + QString m_szServiceName; + virtual int detect(bool bStart); + virtual bool prev(); + virtual bool next(); + virtual bool play(); + virtual bool stop(); + virtual bool pause(); + virtual bool quit(); + virtual MpInterface::PlayerStatus status(); + virtual QString nowPlaying(); + virtual QString mrl(); + virtual QString title(); + virtual QString artist(); + virtual QString genre(); + virtual QString comment(); + virtual QString year(); + virtual QString album(); + virtual int bitRate(); + virtual int sampleRate(); + virtual bool setVol(kvs_int_t &iVol); + virtual int getVol(); + virtual int position(); + virtual int length(); + virtual bool jumpTo(kvs_int_t &iPos); + }; + + class MpAudaciousInterface : public MpMprisInterface + { + public: + MpAudaciousInterface(); + public: + virtual bool quit(); + virtual MpInterface::PlayerStatus status(); + virtual QString mrl(); + virtual int length(); + + virtual int getPlayListPos(); + virtual QString year(); + virtual QString mediaType(); + }; + + class MpBmpxInterface : public MpMprisInterface + { + public: + MpBmpxInterface(); + virtual MpInterface::PlayerStatus status(); + }; + + class MpAmarok2Interface : public MpMprisInterface + { + public: + MpAmarok2Interface(); + }; + + class MpQmmpInterface : public MpMprisInterface + { + public: + MpQmmpInterface(); + }; + + class MpXmms2Interface : public MpMprisInterface + { + public: + MpXmms2Interface(); + }; + + class MpSongbirdInterface : public MpMprisInterface + { + public: + MpSongbirdInterface(); + virtual MpInterface::PlayerStatus status(); + }; + + class MpTotemInterface : public MpMprisInterface + { + public: + MpTotemInterface(); + }; + + class MpVlcInterface : public MpMprisInterface + { + public: + MpVlcInterface(); + }; + + MP_DECLARE_DESCRIPTOR(MpAudaciousInterface) + MP_DECLARE_DESCRIPTOR(MpBmpxInterface) + MP_DECLARE_DESCRIPTOR(MpAmarok2Interface) + MP_DECLARE_DESCRIPTOR(MpQmmpInterface) + MP_DECLARE_DESCRIPTOR(MpXmms2Interface) + MP_DECLARE_DESCRIPTOR(MpSongbirdInterface) + MP_DECLARE_DESCRIPTOR(MpTotemInterface) + MP_DECLARE_DESCRIPTOR(MpVlcInterface) +#endif //COMPILE_ON_WINDOWS + +#endif //_MP_AUDACIOUSINTERFACE_H_ diff --git a/src/modules/mediaplayer/MpWinampInterface.cpp b/src/modules/mediaplayer/MpWinampInterface.cpp new file mode 100644 index 000000000..1fe06d234 --- /dev/null +++ b/src/modules/mediaplayer/MpWinampInterface.cpp @@ -0,0 +1,570 @@ +//============================================================================= +// +// File : MpWinampInterface.cpp +// Creation date : Mon 28 Mar 2005 23:41:50 by Szymon Stefanek +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2005-2010 Szymon Stefanek +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "MpWinampInterface.h" +#include "KviOptions.h" + +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + +#include + +#include "KviLocale.h" +#include "KviModule.h" + +#include + +#define IPC_STARTPLAY 102 +#define IPC_ISPLAYING 104 + +#define IPC_GETOUTPUTTIME 105 +// ** int res = SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETOUTPUTTIME); +// ** +// ** IPC_GETOUTPUTTIME returns the position in milliseconds of the +// ** current song (mode = 0), or the song length, in seconds (mode = 1). +// ** Returns -1 if not playing or error. + +#define IPC_JUMPTOTIME 106 +// ** SendMessage(hwnd_winamp,WM_WA_IPC,ms,IPC_JUMPTOTIME); +// ** IPC_JUMPTOTIME sets the position in milliseconds of the +// ** current song (approximately). + +#define IPC_SETPLAYLISTPOS 121 +// ** SendMessage(hwnd_winamp,WM_WA_IPC,position,IPC_SETPLAYLISTPOS) +// ** IPC_SETPLAYLISTPOS sets the playlsit position to 'position'. + +#define IPC_SETVOLUME 122 +// ** SendMessage(hwnd_winamp,WM_WA_IPC,volume,IPC_SETVOLUME); +// ** IPC_SETVOLUME sets the volume of Winamp (from 0-255). + +#define IPC_GETLISTLENGTH 124 +// ** int length = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTLENGTH); +// ** IPC_GETLISTLENGTH returns the length of the current playlist, in +// ** tracks. + +#define IPC_GETEQDATA 127 +// ** int data=SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA); +// ** IPC_GETEQDATA queries the status of the EQ. +// ** The value returned depends on what 'pos' is set to: +// ** Value Meaning +// ** ------------------ +// ** 0-9 The 10 bands of EQ data. 0-63 (+20db - -20db) +// ** 10 The preamp value. 0-63 (+20db - -20db) +// ** 11 Enabled. zero if disabled, nonzero if enabled. +// ** 12 Autoload. zero if disabled, nonzero if enabled. + +#define IPC_SETEQDATA 128 +// ** SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA); +// ** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SETEQDATA); +// ** IPC_SETEQDATA sets the value of the last position retrieved +// ** by IPC_GETEQDATA. This is pretty lame, and we should provide +// ** an extended version that lets you do a MAKELPARAM(pos,value). +// ** someday... + +#define IPC_GETPLAYLISTFILE 211 +// ** (requires Winamp 2.04+, only usable from plug-ins (not external apps)) +// ** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTFILE); +// ** IPC_GETPLAYLISTFILE gets the filename of the playlist entry [index]. +// ** returns a pointer to it. returns NULL on error. + +#define IPC_GETPLAYLISTTITLE 212 +// * (requires Winamp 2.04+, only usable from plug-ins (not external apps)) +// ** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTTITLE); +// ** IPC_GETPLAYLISTTITLE gets the title of the playlist entry [index]. +// ** returns a pointer to it. returns NULL on error. + +#define IPC_GET_SHUFFLE 250 +// ** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_SHUFFLE); +// ** +// ** IPC_GET_SHUFFLE returns the status of the Shuffle option (1 if set) + +#define IPC_GET_REPEAT 251 +// ** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_REPEAT); +// ** +// ** IPC_GET_REPEAT returns the status of the Repeat option (1 if set) + +#define IPC_SET_SHUFFLE 252 +// ** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_SHUFFLE); +// ** +// ** IPC_SET_SHUFFLE sets the status of the Shuffle option (1 to turn it on) + +#define IPC_SET_REPEAT 253 +// ** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_REPEAT); +// ** +// ** IPC_SET_REPEAT sets the status of the Repeat option (1 to turn it on) + +#define IPC_GETLISTPOS 125 +// ** int pos=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTPOS); +// ** IPC_GETLISTPOS returns the playlist position. A lot like IPC_WRITEPLAYLIST +// ** only faster since it doesn't have to write out the list. Heh, silly me. + +#define IPC_GETINFO 126 +// ** int inf=SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETINFO); +// ** IPC_GETINFO returns info about the current playing song. The value +// ** it returns depends on the value of 'mode'. +// ** Mode Meaning +// ** ------------------ +// ** 0 Samplerate (i.e. 44100) +// ** 1 Bitrate (i.e. 128) +// ** 2 Channels (i.e. 2) + +#define IPC_PLAYFILE 100 +// ** COPYDATASTRUCT cds; +// ** cds.dwData = IPC_PLAYFILE; +// ** cds.lpData = (void *) "file.mp3"; +// ** cds.cbData = strlen((char *) cds.lpData)+1; // include space for null char +// ** SendMessage(hwnd_winamp,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cds); +// ** +// ** This will play the file "file.mp3". + +#define IPC_ISPLAYING 104 +// ** int res = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISPLAYING); +// ** IPC_ISPLAYING returns the status of playback. +// ** If it returns 1, it is playing. if it returns 3, it is paused, +// ** if it returns 0, it is not playing. + +// The following stuff needs PostMessage(hwnd_winamp,WM_COMMAND,id,0); +#define WINAMP_BUTTON1 40044 +#define WINAMP_BUTTON2 40045 +#define WINAMP_BUTTON3 40046 +#define WINAMP_BUTTON4 40047 +#define WINAMP_BUTTON5 40048 + +#define WINAMP_CMD_PREV WINAMP_BUTTON1 +#define WINAMP_CMD_PLAY WINAMP_BUTTON2 +#define WINAMP_CMD_PAUSE WINAMP_BUTTON3 +#define WINAMP_CMD_STOP WINAMP_BUTTON4 +#define WINAMP_CMD_NEXT WINAMP_BUTTON5 + +#define WINAMP_CMD_QUIT 40001 + +#define KVIRC_WM_USER 63112 + +#define KVIRC_WM_USER_CHECK 13123 +#define KVIRC_WM_USER_CHECK_REPLY 13124 +#define KVIRC_WM_USER_GETTITLE 5000 +#define KVIRC_WM_USER_GETFILE 10000 +#define KVIRC_WM_USER_TRANSFER 15000 + + +static QTextCodec * mediaplayer_get_codec() +{ + QTextCodec * c= QTextCodec::codecForName(KVI_OPTION_STRING(KviOption_stringWinampTextEncoding).toAscii()); + if(!c)c = QTextCodec::codecForLocale(); + return c; + +} + +static HWND find_winamp(KviWinampInterface * i) +{ + HWND hWnd = FindWindow("Winamp v1.x",NULL); + if(!hWnd) + { + // try to start the process ? + i->setLastError(__tr2qs_ctx("Can't find a running winamp window","mediaplayer")); + } + return hWnd; +} + + +MP_IMPLEMENT_DESCRIPTOR( + KviWinampInterface, + "winamp", + __tr2qs_ctx( + "An interface to the popupar Winamp media player.\n" \ + "You can download it from http://www.winamp.com.\n" \ + "To use all the features of this interface you must " \ + "copy the gen_kvirc.dll plugin found in the KVIrc " \ + "distribution directory to the Winamp plugins folder " \ + "and restart winamp." + , + "mediaplayer" + ) +) + + +KviWinampInterface::KviWinampInterface() +: MpInterface() +{ +} + +KviWinampInterface::~KviWinampInterface() +{ +} + + +int KviWinampInterface::detect(bool bStart) +{ + if(find_winamp(this))return 80; + // FIXME : check for Programs Folder\Winamp\Winamp.exe ? + // FIXME : if bStart try to start winamp.exe ? + return 50; +} + +#define MP_WINAMP_SENDMESSAGE(__cmdname,__wmmsg,__lparam,__wparam) \ + bool KviWinampInterface::__cmdname() \ + { \ + HWND hWinamp = find_winamp(this); \ + if(hWinamp)SendMessage(hWinamp,__wmmsg,__lparam,__wparam); \ + return hWinamp != 0; \ + } + +#define MP_WINAMP_WM_USER(__cmdname,_ipcmsg) MP_WINAMP_SENDMESSAGE(__cmdname,WM_USER,0,_ipcmsg) +#define MP_WINAMP_WM_COMMAND(__cmdname,_cmdmsg) MP_WINAMP_SENDMESSAGE(__cmdname,WM_COMMAND,_cmdmsg,0) + +MP_WINAMP_WM_USER(play,IPC_STARTPLAY) +MP_WINAMP_WM_COMMAND(stop,WINAMP_CMD_STOP) +MP_WINAMP_WM_COMMAND(next,WINAMP_CMD_NEXT) +MP_WINAMP_WM_COMMAND(prev,WINAMP_CMD_PREV) +MP_WINAMP_WM_COMMAND(pause,WINAMP_CMD_PAUSE) +MP_WINAMP_WM_COMMAND(quit,WINAMP_CMD_QUIT) + + +int KviWinampInterface::length() +{ + int leninsecs = -1; + HWND hWinamp = find_winamp(this); + if(hWinamp)leninsecs = SendMessage(hWinamp,WM_USER,1,IPC_GETOUTPUTTIME); + return leninsecs * 1000; +} + +int KviWinampInterface::position() +{ + int leninmsecs = -1; + HWND hWinamp = find_winamp(this); + if(hWinamp)leninmsecs = SendMessage(hWinamp,WM_USER,0,IPC_GETOUTPUTTIME); + return leninmsecs; +} + +int KviWinampInterface::bitRate() +{ + int ret = -1; + HWND hWinamp = find_winamp(this); + if(hWinamp)ret = SendMessage(hWinamp,WM_USER,1,IPC_GETINFO); + return ret; +} + +int KviWinampInterface::sampleRate() +{ + int ret = -1; + HWND hWinamp = find_winamp(this); + if(hWinamp)ret = SendMessage(hWinamp,WM_USER,0,IPC_GETINFO); + return ret; +} + +int KviWinampInterface::channels() +{ + int ret = -1; + HWND hWinamp = find_winamp(this); + if(hWinamp)ret = SendMessage(hWinamp,WM_USER,2,IPC_GETINFO); + return ret; +} + +MpInterface::PlayerStatus KviWinampInterface::status() +{ + HWND hWinamp = find_winamp(this); + int ret = 1000; + if(hWinamp)ret = SendMessage(hWinamp,WM_USER,0,IPC_ISPLAYING); + switch(ret) + { + case 0: + return MpInterface::Stopped; + break; + case 3: + return MpInterface::Paused; + break; + case 1: + return MpInterface::Playing; + break; + default: + return MpInterface::Unknown; + break; + } + return MpInterface::Unknown; +} + +QString KviWinampInterface::mrl() +{ + QString ret; + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + int ret2 = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_CHECK); + + if(ret2 =! KVIRC_WM_USER_CHECK_REPLY) + { + setLastError(__tr2qs_ctx("The winamp plugin has not been installed properly. Check /help mediaplayer.nowplaying","mediaplayer")); + return ret; + } + + int len = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_GETFILE); + + if(len < 4096) + { + char szBuffer[4096]; + + for(int i = 0;i < len;i++) + { + szBuffer[i] = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_TRANSFER + i); + } + szBuffer[len] = '\0'; + QTextCodec *c=mediaplayer_get_codec(); + if (c) ret = c->toUnicode(szBuffer); + else ret=szBuffer; + if(!ret.startsWith("http://",Qt::CaseInsensitive)) + ret.prepend("file://"); + } + } + return ret; +} + +QString KviWinampInterface::nowPlaying() +{ + QString ret; + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + int retpippo = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_CHECK); + if(retpippo =! KVIRC_WM_USER_CHECK_REPLY) + { + setLastError(__tr2qs_ctx("The winamp plugin has not been installed properly. Check /help mediaplayer.nowplaying","mediaplayer") ); + return ret; + } + + int len = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_GETTITLE); + + if(len < 4096) + { + char szBuffer[4096]; + + for(int i = 0;i < len;i++) + { + szBuffer[i] = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_TRANSFER + i); + } + szBuffer[ len ] = '\0'; + + QTextCodec *c=mediaplayer_get_codec(); + if (c) ret = c->toUnicode(szBuffer); + else ret=szBuffer; + } + } + return ret; +} + +bool KviWinampInterface::playMrl(const QString &mrl) +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + QTextCodec *c=mediaplayer_get_codec(); + KviCString szMrl = c ? c->fromUnicode(mrl) : mrl.toUtf8(); + COPYDATASTRUCT cds; + cds.dwData = IPC_PLAYFILE; + cds.lpData = (void *)szMrl.ptr(); + cds.cbData = szMrl.len() + 1; // include space for null char + SendMessage(hWinamp,WM_COPYDATA,(WPARAM)NULL,(LPARAM) &cds); + return true; + } + return false; +} + +bool KviWinampInterface::setVol(kvs_int_t &iVol) +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + SendMessage(hWinamp,WM_USER,iVol,IPC_SETVOLUME); + return true; + } + return false; +} + +int KviWinampInterface::getVol() +{ + int ret = -1; + HWND hWinamp = find_winamp(this); +#if defined(COMPILE_ON_MINGW) + if(hWinamp)ret = SendMessage(hWinamp,WM_USER,666,IPC_SETVOLUME); +#else + if(hWinamp)ret = SendMessage(hWinamp,WM_USER,-666,IPC_SETVOLUME); +#endif + return ret; +} + +bool KviWinampInterface::jumpTo(kvs_int_t &iPos) +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + SendMessage(hWinamp,WM_USER,iPos,IPC_JUMPTOTIME); + return true; + } + return false; +} +bool KviWinampInterface::hide() +{ + HWND hWinamp = find_winamp(this); + HWND hWinampPE = FindWindow("Winamp PE",NULL); /*Playlist*/ + HWND hWinampEQ = FindWindow("Winamp EQ",NULL); /*Equalizer*/ + HWND hWinampMB = FindWindow("Winamp MB",NULL); /*MiniBrowser*/ + HWND hWinampGen = FindWindow("Winamp Gen",NULL); /*Library*/ + HWND hWinampVideo = FindWindow("Winamp Video",NULL); /*Video*/ + if(hWinamp) + { + ShowWindow(hWinamp, SW_HIDE); + if(hWinampPE || hWinampEQ || hWinampMB || hWinampGen || hWinampVideo ) + { + if(hWinampPE) + ShowWindow(hWinampPE, SW_HIDE); + if(hWinampEQ) + ShowWindow(hWinampEQ, SW_HIDE); + if(hWinampMB) + ShowWindow(hWinampMB, SW_HIDE); + if(hWinampGen) + ShowWindow(hWinampGen, SW_HIDE); + if(hWinampVideo) + ShowWindow(hWinampVideo, SW_HIDE); + return true; + } + return true; + } + return false; +} + +bool KviWinampInterface::show() +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + ShowWindow(hWinamp, SW_SHOW); + return true; + } + return false; +} + +bool KviWinampInterface::minimize() +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + ShowWindow(hWinamp, SW_SHOWMINIMIZED); + return true; + } + return false; +} + +bool KviWinampInterface::setPlayListPos(kvs_int_t &iPos) +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + SendMessage(hWinamp,WM_USER,iPos,IPC_SETPLAYLISTPOS); + return true; + } + return false; +} + +int KviWinampInterface::getPlayListPos() +{ + int ret = -1; + HWND hWinamp = find_winamp(this); + if(hWinamp)ret = SendMessage(hWinamp,WM_USER,2,IPC_GETLISTPOS); + return ret; +} + +int KviWinampInterface::getListLength() +{ + int ret = -1; + HWND hWinamp = find_winamp(this); + if(hWinamp)ret = SendMessage(hWinamp,WM_USER,2,IPC_GETLISTLENGTH); + return ret; +} + +bool KviWinampInterface::setEqData(kvs_int_t &iPos, kvs_int_t &iVal) +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + SendMessage(hWinamp,WM_USER,iPos,IPC_GETEQDATA); + SendMessage(hWinamp,WM_USER,iVal,IPC_SETEQDATA); + return true; + } + return false; +} + +int KviWinampInterface::getEqData(kvs_int_t &ival) +{ + HWND hWinamp = find_winamp(this); + int ret = -1; + if(hWinamp) + { + ret = SendMessage(hWinamp,WM_USER,ival,IPC_GETEQDATA); + return ret; + } + return ret; +} + +bool KviWinampInterface::getRepeat() +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + bool bRepeat = SendMessage(hWinamp,WM_USER,0,IPC_GET_REPEAT); + return bRepeat; + } + return false; +} + +bool KviWinampInterface::getShuffle() +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + bool bShuffle = SendMessage(hWinamp,WM_USER,0,IPC_GET_SHUFFLE); + return bShuffle; + } + return false; +} + +bool KviWinampInterface::setShuffle(bool &bVal) +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + bool bRepeat = SendMessage(hWinamp,WM_USER,bVal,IPC_SET_SHUFFLE); + return bRepeat; + } + return false; +} + +bool KviWinampInterface::setRepeat(bool &bVal) +{ + HWND hWinamp = find_winamp(this); + if(hWinamp) + { + bool bShuffle = SendMessage(hWinamp,WM_USER,bVal,IPC_SET_REPEAT); + return bShuffle; + } + return false; +} +#endif //COMPILE_ON_WINDOWS diff --git a/src/modules/mediaplayer/MpWinampInterface.h b/src/modules/mediaplayer/MpWinampInterface.h new file mode 100644 index 000000000..623e5f7fe --- /dev/null +++ b/src/modules/mediaplayer/MpWinampInterface.h @@ -0,0 +1,76 @@ +#ifndef _MP_WINAMPINTERFACE_H_ +#define _MP_WINAMPINTERFACE_H_ +//============================================================================= +// +// File : MpWinampInterface.h +// Creation date : Mon 28 Mar 2005 23:41:50 by Szymon Stefanek +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2005-2010 Szymon Stefanek +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" + +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + + #include "MpInterface.h" + + class KviWinampInterface : public MpInterface + { + public: + KviWinampInterface(); + ~KviWinampInterface(); + public: + virtual int detect(bool bStart); + virtual bool prev(); + virtual bool next(); + virtual bool play(); + virtual bool stop(); + virtual bool pause(); + virtual bool quit(); + virtual QString nowPlaying(); + virtual QString mrl(); + virtual int position(); + virtual int length(); + virtual bool playMrl(const QString &mrl); + virtual bool setVol(kvs_int_t &iVol); + virtual int getVol(); + virtual bool jumpTo(kvs_int_t &iPos); + virtual int sampleRate(); + virtual int bitRate(); + virtual int channels(); + virtual bool hide(); + virtual bool show(); + virtual bool minimize(); + virtual int getPlayListPos(); + virtual bool setPlayListPos(kvs_int_t &iPos); + virtual int getListLength(); + virtual int getEqData(kvs_int_t &ival); + virtual bool setEqData(kvs_int_t &iPos, kvs_int_t &iVal); + virtual bool getRepeat(); + virtual bool getShuffle(); + virtual bool setRepeat(bool &bVal); + virtual bool setShuffle(bool &bVal); + virtual MpInterface::PlayerStatus status(); + }; + + MP_DECLARE_DESCRIPTOR(KviWinampInterface) + +#endif //COMPILE_ON_WINDOWS + +#endif //!_MP_WINAMPINTERFACE_H_ diff --git a/src/modules/mediaplayer/MpXmmsInterface.cpp b/src/modules/mediaplayer/MpXmmsInterface.cpp new file mode 100644 index 000000000..24890f9dc --- /dev/null +++ b/src/modules/mediaplayer/MpXmmsInterface.cpp @@ -0,0 +1,358 @@ +//============================================================================= +// +// File : MpXmmsInterface.cpp +// Creation date : Fri 25 Mar 2005 20:04:54 by Szymon Stefanek +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2005-2010 Szymon Stefanek +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// Thnx to Alexander Stillich for Audacious +// media player interface hints :) +// +//============================================================================= + +#include "MpXmmsInterface.h" + +#if (!defined(COMPILE_ON_WINDOWS) && !defined(COMPILE_ON_MAC) && !defined(COMPILE_ON_MINGW)) + +#include "KviLocale.h" + +MP_IMPLEMENT_DESCRIPTOR( + KviXmmsInterface, + "xmms", + __tr2qs_ctx( + "An interface to the popular UNIX xmms media player.\n" \ + "Download it from http://legacy.xmms2.org\n" + , + "mediaplayer" + ) +) + +MP_IMPLEMENT_DESCRIPTOR( + KviAudaciousClassicInterface, + "audacious classic", + __tr2qs_ctx( + "An interface to the popular UNIX audacious media player.\n" \ + "Download it from http://audacious-media-player.org\n" + , + "mediaplayer" + ) +) + +static const char *xmms_lib_names[] = +{ + "libxmms.so", + "libxmms.so.1", + "/usr/lib/libxmms.so", + "/usr/lib/libxmms.so.1", + "/usr/local/lib/libxmms.so", + "/usr/local/lib/libxmms.so.1", + 0 +}; + +static const char *audacious_lib_names[] = +{ + "libaudacious.so", + "libaudacious.so.4", + "/usr/lib/libaudacious.so", + "/usr/lib/libaudacious.so.4", + "/usr/local/lib/libaudacious.so", + "/usr/local/lib/libaudacious.so.4", + 0 +}; + + + +KviXmmsInterface::KviXmmsInterface() +: MpInterface() +{ + m_pPlayerLibrary = 0; + m_szPlayerLibraryName = "libxmms.so"; + m_pLibraryPaths = xmms_lib_names; +} + +KviXmmsInterface::~KviXmmsInterface() +{ + if(m_pPlayerLibrary) + { + m_pPlayerLibrary->unload(); + delete m_pPlayerLibrary; + m_pPlayerLibrary = 0; + } +} + +KviAudaciousClassicInterface::KviAudaciousClassicInterface() +: KviXmmsInterface() +{ + m_szPlayerLibraryName = "libaudacious.so"; + m_pLibraryPaths = audacious_lib_names; +} + +KviAudaciousClassicInterface::~KviAudaciousClassicInterface() +{ +} + +bool KviXmmsInterface::loadPlayerLibrary() +{ + if(m_pPlayerLibrary && m_pPlayerLibrary->isLoaded())return true; + + const char **lib_name = m_pLibraryPaths; + while(*lib_name) + { + m_pPlayerLibrary = new QLibrary(*lib_name); + if(m_pPlayerLibrary->load()) + { + m_szPlayerLibraryName = *lib_name; + return true; + } + delete m_pPlayerLibrary; + m_pPlayerLibrary = 0; + lib_name++; + } + return false; +} + +void * KviXmmsInterface::lookupSymbol(const char * szSymbolName) +{ + if(!m_pPlayerLibrary) + { + if(!loadPlayerLibrary()) + { + QString tmp; + KviQString::sprintf(tmp,__tr2qs_ctx("Can't load the player library (%Q)","mediaplayer"),&m_szPlayerLibraryName); + setLastError(tmp); + return 0; + } + } + void * symptr =m_pPlayerLibrary->resolve(szSymbolName); + if(!symptr) + { + QString tmp; + KviQString::sprintf(tmp,__tr2qs_ctx("Can't find symbol %s in %Q","mediaplayer"),szSymbolName,&m_szPlayerLibraryName); + setLastError(tmp); + } + return symptr; +} + + +int KviXmmsInterface::detect(bool) +{ + void * sym = lookupSymbol("xmms_remote_play"); + return sym ? 80 : 0; +} + +#define XMMS_SIMPLE_CALL(__symname) \ + void (*sym)(int) = (void (*)(int))lookupSymbol(__symname); \ + if(!sym)return false; \ + sym(0); \ + return true; + +bool KviXmmsInterface::prev() +{ + XMMS_SIMPLE_CALL("xmms_remote_playlist_prev") +} + +bool KviXmmsInterface::next() +{ + XMMS_SIMPLE_CALL("xmms_remote_playlist_next") +} + +bool KviXmmsInterface::play() +{ + XMMS_SIMPLE_CALL("xmms_remote_play") +} + +bool KviXmmsInterface::stop() +{ + XMMS_SIMPLE_CALL("xmms_remote_stop") +} + +bool KviXmmsInterface::pause() +{ + XMMS_SIMPLE_CALL("xmms_remote_pause") +} + +bool KviXmmsInterface::quit() +{ + XMMS_SIMPLE_CALL("xmms_remote_quit") +} + +bool KviXmmsInterface::jumpTo(kvs_int_t &iPos) +{ + void (*sym)(int,int) = (void (*)(int,int))lookupSymbol("xmms_remote_jump_to_time"); + if(!sym)return false; + sym(0,iPos); + return true; +} + +bool KviXmmsInterface::setVol(kvs_int_t &iVol) +{ + void (*sym)(int,int) = (void (*)(int,int))lookupSymbol("xmms_remote_set_main_volume"); + if(!sym)return false; + sym(0,100*iVol/255); + return true; +} + +int KviXmmsInterface::getVol() +{ + int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_main_volume"); + if(!sym)return -1; + int iVol = sym(0); + return iVol * 255 /100; +} + +bool KviXmmsInterface::getRepeat() +{ + bool (*sym)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_repeat"); + if(!sym)return false; + bool ret = sym(0); + return ret; +} + +bool KviXmmsInterface::setRepeat(bool &bVal) +{ + bool (*sym1)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_repeat"); + if(!sym1)return false; + bool bNow = sym1(0); + if(bNow != bVal) + { + void (*sym2)(int) = (void (*)(int))lookupSymbol("xmms_remote_toggle_repeat"); + if(!sym2)return false; + sym2(0); + } + return true; +} + +bool KviXmmsInterface::getShuffle() +{ + bool (*sym)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_shuffle"); + if(!sym)return false; + bool ret = sym(0); + return ret; +} + +bool KviXmmsInterface::setShuffle(bool &bVal) +{ + bool (*sym1)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_shuffle"); + if(!sym1)return false; + bool bNow = sym1(0); + if(bNow != bVal) + { + void (*sym2)(int) = (void (*)(int))lookupSymbol("xmms_remote_toggle_shuffle"); + if(!sym2)return false; + sym2(0); + } + return true; +} + +MpInterface::PlayerStatus KviXmmsInterface::status() +{ + bool (*sym1)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_paused"); + if(sym1) + { + if(sym1(0))return MpInterface::Paused; + bool (*sym2)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_playing"); + if(sym2) + { + if(sym2(0))return MpInterface::Playing; + else return MpInterface::Stopped; + } + } + + return MpInterface::Unknown; +} + +bool KviXmmsInterface::playMrl(const QString &mrl) +{ + void (*sym)(int,char *) = (void (*)(int,char *))lookupSymbol("xmms_remote_playlist_add_url_string"); + QByteArray tmp = mrl.toLocal8Bit(); + if(!tmp.isEmpty()) + { + if(sym) + { + sym(0,tmp.data()); + int (*sym1)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_length"); + if(sym1) + { + int len = sym1(0); + if(len > 0) + { + void (*sym2)(int,int) = (void (*)(int,int))lookupSymbol("xmms_remote_set_playlist_pos"); + if(sym2) + { + sym2(0,len - 1); + } else return false; + } else return false; + } else return false; + } else return false; + } + return true; +} + +QString KviXmmsInterface::nowPlaying() +{ + int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos"); + if(!sym)return QString(); + int pos = sym(0); + char * (*sym2)(int,int) = (char * (*)(int,int))lookupSymbol("xmms_remote_get_playlist_title"); + if(!sym2)return QString(); + return QString::fromLocal8Bit(sym2(0,pos)); +} + +QString KviXmmsInterface::mrl() +{ + int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos"); + if(!sym)return QString(); + int pos = sym(0); + char * (*sym2)(int,int) = (char * (*)(int,int))lookupSymbol("xmms_remote_get_playlist_file"); + if(!sym2)return QString(); + QString ret = QString::fromLocal8Bit(sym2(0,pos)); + if(ret.length() > 1) + if(ret[0] == '/')ret.prepend("file://"); + return ret; +} + +int KviXmmsInterface::position() +{ + int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos"); + if(!sym)return -1; + int pos = sym(0); + int (*sym2)(int,int) = (int (*)(int,int))lookupSymbol("xmms_remote_get_output_time"); + if(!sym2)return -1; + return sym2(0,pos); +} + +int KviXmmsInterface::length() +{ + int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos"); + if(!sym)return -1; + int pos = sym(0); + int (*sym2)(int,int) = (int (*)(int,int))lookupSymbol("xmms_remote_get_playlist_time"); + if(!sym2)return -1; + return sym2(0,pos); +} + +int KviXmmsInterface::getPlayListPos() +{ + int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos"); + if(!sym)return -1; + return sym(0); +} + + + +#endif //!COMPILE_ON_WINDOWS diff --git a/src/modules/mediaplayer/MpXmmsInterface.h b/src/modules/mediaplayer/MpXmmsInterface.h new file mode 100644 index 000000000..3c49c036b --- /dev/null +++ b/src/modules/mediaplayer/MpXmmsInterface.h @@ -0,0 +1,86 @@ +#ifndef _MP_XMMSINTERFACE_H_ +#define _MP_XMMSINTERFACE_H_ +//============================================================================= +// +// File : MpXmmsInterface.h +// Creation date : Fri 25 Mar 2005 20:04:54 by Szymon Stefanek +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2005-2010 Szymon Stefanek +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// Thnx to Alexander Stillich for Audacious +// media player interface hints :) +// +//============================================================================= + +#include "MpInterface.h" + +#include "kvi_settings.h" + +#include + +#if !defined(COMPILE_ON_WINDOWS) && !defined(COMPILE_ON_MINGW) + class KviXmmsInterface : public MpInterface + { + public: + KviXmmsInterface(); + virtual ~KviXmmsInterface(); + protected: + QLibrary* m_pPlayerLibrary; + QString m_szPlayerLibraryName; + const char ** m_pLibraryPaths; + public: + virtual int detect(bool bStart); + virtual bool prev(); + virtual bool next(); + virtual bool play(); + virtual bool stop(); + virtual bool pause(); + virtual bool quit(); + virtual bool jumpTo(kvs_int_t &iPos); + virtual bool setVol(kvs_int_t &iVol); + virtual int getVol(); + virtual MpInterface::PlayerStatus status(); + virtual QString nowPlaying(); + virtual bool playMrl(const QString &mrl); + virtual QString mrl(); + virtual int getPlayListPos(); + virtual int position(); + virtual int length(); + virtual bool getRepeat(); + virtual bool getShuffle(); + virtual bool setRepeat(bool &bVal); + virtual bool setShuffle(bool &bVal); + protected: + bool loadPlayerLibrary(); + void * lookupSymbol(const char * szSymbolName); + }; + + MP_DECLARE_DESCRIPTOR(KviXmmsInterface) + + class KviAudaciousClassicInterface : public KviXmmsInterface + { + public: + KviAudaciousClassicInterface(); + virtual ~KviAudaciousClassicInterface(); + }; + + MP_DECLARE_DESCRIPTOR(KviAudaciousClassicInterface) + +#endif //COMPILE_ON_WINDOWS + +#endif //_MP_XMMSINTERFACE_H_ diff --git a/src/modules/mediaplayer/libkvimediaplayer.cpp b/src/modules/mediaplayer/libkvimediaplayer.cpp index 9da76e490..c20fb421c 100644 --- a/src/modules/mediaplayer/libkvimediaplayer.cpp +++ b/src/modules/mediaplayer/libkvimediaplayer.cpp @@ -24,11 +24,11 @@ // //============================================================================= -#include "mp_interface.h" -#include "mp_amipinterface.h" -#include "mp_mprisinterface.h" -#include "mp_winampinterface.h" -#include "mp_xmmsinterface.h" +#include "MpInterface.h" +#include "MpAmipInterface.h" +#include "MpMprisInterface.h" +#include "MpWinampInterface.h" +#include "MpXmmsInterface.h" #include "KviModule.h" #include "KviOptions.h" @@ -36,19 +36,19 @@ #include "kvi_out.h" #include -static KviPointerList * g_pDescriptorList = 0; +static KviPointerList * g_pDescriptorList = 0; -static KviMediaPlayerInterface * g_pMPInterface = 0; +static MpInterface * g_pMPInterface = 0; -static KviMediaPlayerInterface * auto_detect_player(KviWindow * pOut = 0) +static MpInterface * auto_detect_player(KviWindow * pOut = 0) { int iBest = 0; - KviMediaPlayerInterface * pBest = 0; - KviMediaPlayerInterfaceDescriptor * d; - KviMediaPlayerInterfaceDescriptor * pDBest = 0; + MpInterface * pBest = 0; + MpInterfaceDescriptor * d; + MpInterfaceDescriptor * pDBest = 0; for(d = g_pDescriptorList->first();d;d = g_pDescriptorList->next()) { - KviMediaPlayerInterface * i = d->instance(); + MpInterface * i = d->instance(); if(i) { int iScore = i->detect(false); @@ -74,7 +74,7 @@ static KviMediaPlayerInterface * auto_detect_player(KviWindow * pOut = 0) // no sure player found... try again with a destructive test for(d = g_pDescriptorList->first();d;d = g_pDescriptorList->next()) { - KviMediaPlayerInterface * i = d->instance(); + MpInterface * i = d->instance(); if(i) { int iScore = i->detect(true); @@ -460,7 +460,7 @@ MP_KVS_COMMAND(setPlayer) KVSM_PARAMETER("player",KVS_PT_STRING,0,szPlayer) KVSM_PARAMETERS_END(c) - for(KviMediaPlayerInterfaceDescriptor * d = g_pDescriptorList->first();d;d = g_pDescriptorList->next()) + for(MpInterfaceDescriptor * d = g_pDescriptorList->first();d;d = g_pDescriptorList->next()) { if(d->name() == szPlayer) { @@ -523,7 +523,7 @@ MP_KVS_FUNCTION(playerList) KviKvsArray* pArray = new KviKvsArray(); int id=0; - for(KviMediaPlayerInterfaceDescriptor * d = g_pDescriptorList->first();d;d = g_pDescriptorList->next()) + for(MpInterfaceDescriptor * d = g_pDescriptorList->first();d;d = g_pDescriptorList->next()) { pArray->set(id++,new KviKvsVariant(d->name())); } @@ -1456,16 +1456,16 @@ MP_KVS_FUNCTION(status) // KVSM_PARAMETERS_END(c) MP_KVS_FAIL_ON_NO_INTERFACE - KviMediaPlayerInterface::PlayerStatus eStat = g_pMPInterface->status(); + MpInterface::PlayerStatus eStat = g_pMPInterface->status(); switch(eStat) { - case KviMediaPlayerInterface::Stopped: + case MpInterface::Stopped: c->returnValue()->setString("stopped"); break; - case KviMediaPlayerInterface::Playing: + case MpInterface::Playing: c->returnValue()->setString("playing"); break; - case KviMediaPlayerInterface::Paused: + case MpInterface::Paused: c->returnValue()->setString("paused"); break; default: @@ -1606,24 +1606,24 @@ MP_KVS_COMMAND(setShuffle) static bool mediaplayer_module_init( KviModule * m ) { - g_pDescriptorList = new KviPointerList; + g_pDescriptorList = new KviPointerList; g_pDescriptorList->setAutoDelete(true); #if (defined(COMPILE_DBUS_SUPPORT) && !defined(COMPILE_ON_WINDOWS) && !defined(COMPILE_ON_MAC) && !defined(COMPILE_ON_MINGW)) - g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviAudaciousInterface)); + g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(MpAudaciousInterface)); g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviAudaciousClassicInterface)); g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviXmmsInterface)); - g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviXmms2Interface)); - g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviBmpxInterface)); - g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviAmarok2Interface)); - g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviQmmpInterface)); - g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviSongbirdInterface)); - g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviTotemInterface)); - g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviVlcInterface)); + g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(MpXmms2Interface)); + g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(MpBmpxInterface)); + g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(MpAmarok2Interface)); + g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(MpQmmpInterface)); + g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(MpSongbirdInterface)); + g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(MpTotemInterface)); + g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(MpVlcInterface)); #endif #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviAmipInterface)); + g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(MpAmipInterface)); g_pDescriptorList->append(MP_CREATE_DESCRIPTOR(KviWinampInterface)); #endif g_pMPInterface = 0; @@ -1632,7 +1632,7 @@ static bool mediaplayer_module_init( KviModule * m ) { g_pMPInterface = auto_detect_player(); } else { - for(KviMediaPlayerInterfaceDescriptor * d = g_pDescriptorList->first();d;d = g_pDescriptorList->next()) + for(MpInterfaceDescriptor * d = g_pDescriptorList->first();d;d = g_pDescriptorList->next()) { if(d->name() == KVI_OPTION_STRING(KviOption_stringPreferredMediaPlayer)) { @@ -1724,7 +1724,7 @@ static bool mediaplayer_module_ctrl(KviModule *,const char * operation,void * pa { // we expect param to be a pointer to QStringList QStringList * l = (QStringList *)param; - for(KviMediaPlayerInterfaceDescriptor * d = g_pDescriptorList->first();d;d = g_pDescriptorList->next()) + for(MpInterfaceDescriptor * d = g_pDescriptorList->first();d;d = g_pDescriptorList->next()) { l->append(d->name()); } diff --git a/src/modules/mediaplayer/mp_amipinterface.cpp b/src/modules/mediaplayer/mp_amipinterface.cpp deleted file mode 100644 index df4e309cd..000000000 --- a/src/modules/mediaplayer/mp_amipinterface.cpp +++ /dev/null @@ -1,415 +0,0 @@ -//============================================================================= -// -// File : mp_amipinterface.cpp -// Creation date : Sun 27 Mar 2005 16:55:09 by Szymon Stefanek -// -// This file is part of the KVIrc IRC client distribution -// Copyright (C) 2005-2010 Szymon Stefanek -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "mp_amipinterface.h" -#include "KviOptions.h" - -#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - -#include - -#include "KviLocale.h" -#include "KviModule.h" - -#include - -enum ac_StartMode -{ - AC_START_ALL = 0, - AC_START_CLIENT, - AC_START_SERVER, - AC_START_NONE -}; - -enum ac_ErrorCode -{ - AC_ERR_NOERROR = 0, - AC_ERR_CLIENTISNULL, - AC_ERR_EXCEPTION, - AC_ERR_CONNECTIONFAILED, - AC_ERR_SERVERNOTRUNNING -}; - -#define AC_BUFFER_SIZE 2048 - -static HINSTANCE amip_dll = NULL; - -#define MP_AC_DYNPTR(__rettype,__func,__args) \ - typedef __rettype (CALLBACK* lp_##__func)(__args); \ - lp_##__func __func - -#define MP_AC_FUNC(__func) \ - __func = (lp_##__func)GetProcAddress(amip_dll,#__func); \ - if(!__func) { \ - FreeLibrary(amip_dll); \ - return false; \ - } - -#define COMMA() , - -MP_AC_DYNPTR(void, ac_init, int mode); -MP_AC_DYNPTR(void, ac_uninit, void); -MP_AC_DYNPTR(void, ac_getDestHost, char *out); -MP_AC_DYNPTR(int, ac_getDestPort, void); -MP_AC_DYNPTR(bool, ac_pingServer, const char *host COMMA() int port COMMA() int timeout); -MP_AC_DYNPTR(int, ac_exec, const char *cmd); -MP_AC_DYNPTR(int, ac_eval, const char *cmd COMMA() char *result); - - -static bool loadAmipDll() -{ - amip_dll = LoadLibrary("ac.dll"); - if (!amip_dll) return false; - - MP_AC_FUNC(ac_init); - MP_AC_FUNC(ac_uninit); - MP_AC_FUNC(ac_getDestHost); - MP_AC_FUNC(ac_getDestPort); - MP_AC_FUNC(ac_pingServer); - MP_AC_FUNC(ac_eval); - MP_AC_FUNC(ac_exec); - - return true; -}; - -static QTextCodec * mediaplayer_get_codec() -{ - QTextCodec * c= QTextCodec::codecForName(KVI_OPTION_STRING(KviOption_stringWinampTextEncoding).toAscii()); - if(!c) - c = QTextCodec::codecForLocale(); - return c; -} - -MP_IMPLEMENT_DESCRIPTOR( - KviAmipInterface, - "amip", - __tr2qs_ctx( - "An interface to the AMIP plug-in.\n" \ - "You can download it from http://amip.tools-for.net\n" \ - "To use this interface you must " \ - "install AMIP plug-in for your player." - , - "mediaplayer" - ) -) - - - -KviAmipInterface::KviAmipInterface() -: KviMediaPlayerInterface() -{ - if(!amip_dll) { - bool res = loadAmipDll(); - if(!res) { - amip_dll = NULL; - return; - } - ac_init(AC_START_CLIENT); - } -} - -KviAmipInterface::~KviAmipInterface() -{ - if(!amip_dll) return; - ac_uninit(); - FreeLibrary(amip_dll); - amip_dll = NULL; -} - - -int KviAmipInterface::detect(bool bStart) -{ - if(!amip_dll) return 0; - char host[AC_BUFFER_SIZE]; - ac_getDestHost(host); - if(ac_pingServer(host, ac_getDestPort(), 5000)) return 99; - return 1; -} - -#define MP_AMIP_COMMAND(__cmdname,__acmd) \ - bool KviAmipInterface::__cmdname() \ - { \ - return (ac_exec(__acmd) == AC_ERR_NOERROR); \ - } - -MP_AMIP_COMMAND(play,"control play") -MP_AMIP_COMMAND(stop,"control stop") -MP_AMIP_COMMAND(next,"control >") -MP_AMIP_COMMAND(prev,"control <") -MP_AMIP_COMMAND(pause,"control pause") -MP_AMIP_COMMAND(quit,"control exit") - -// helper function for evaluating variables returning integers -int eval_int(const char *var) -{ - if(!amip_dll) return -1; - char buff[AC_BUFFER_SIZE]; - int res = -1; - if (AC_ERR_NOERROR == ac_eval(var, buff)) - res = atoi(buff); - return res; -} - -QString eval_str(const char *var) -{ - QString res; - if(!amip_dll) return res; - char buff[AC_BUFFER_SIZE]; - if (AC_ERR_NOERROR == ac_eval(var, buff)) - res.append(buff); - return res; -} - -int KviAmipInterface::length() -{ - return eval_int("var_sl") * 1000; -} - -int KviAmipInterface::position() -{ - return eval_int("var_psec") * 1000; -} - -int KviAmipInterface::bitRate() -{ - return eval_int("var_br"); -} - -int KviAmipInterface::sampleRate() -{ - return eval_int("var_sr"); -} - -int KviAmipInterface::channels() -{ - int ret = -1; - if(eval_str("var_typ").startsWith("Stereo")) - ret = 2; - else if(eval_str("var_typ").startsWith("Mono")) - ret = 1; - return ret; -} - -KviMediaPlayerInterface::PlayerStatus KviAmipInterface::status() -{ - int ret = eval_int("var_stat"); - switch(ret) - { - case 0: - return KviMediaPlayerInterface::Stopped; - break; - case 3: - return KviMediaPlayerInterface::Paused; - break; - case 1: - return KviMediaPlayerInterface::Playing; - break; - default: - return KviMediaPlayerInterface::Unknown; - break; - } - return KviMediaPlayerInterface::Unknown; -} - -QString KviAmipInterface::mrl() -{ - QString ret; - QString fn = eval_str("var_fn"); - QTextCodec *c=mediaplayer_get_codec(); - if (c) ret = c->toUnicode(fn.toAscii()); - else ret=fn; - if(!ret.startsWith("http://",Qt::CaseInsensitive)) - ret.prepend("file://"); - - return ret; -} - -QString getAmipString(const char * var) -{ - QString ret; - QString s = eval_str(var); - QTextCodec *c=mediaplayer_get_codec(); - if (c) ret = c->toUnicode(s.toAscii()); - else ret=s; - return ret; -} - -QString KviAmipInterface::nowPlaying() -{ - return getAmipString("var_s"); -} - -QString KviAmipInterface::artist() -{ - return getAmipString("var_1"); -} - -QString KviAmipInterface::title() -{ - return getAmipString("var_2"); -} - -QString KviAmipInterface::album() -{ - return getAmipString("var_4"); -} - -QString KviAmipInterface::year() -{ - return getAmipString("var_5"); -} - -QString KviAmipInterface::comment() -{ - return getAmipString("var_6"); -} - -QString KviAmipInterface::genre() -{ - return getAmipString("var_7"); -} - -bool KviAmipInterface::setVol(kvs_int_t &iVol) -{ - if(!amip_dll) return false; - char volcmd[AC_BUFFER_SIZE]; - sprintf(volcmd, "control vol %d", iVol); - return (ac_exec(volcmd) == AC_ERR_NOERROR); -} - -int KviAmipInterface::getVol() -{ - return eval_int("var_vol"); -} - -bool KviAmipInterface::jumpTo(kvs_int_t &iPos) -{ - if(!amip_dll) return false; - char jmpcmd[AC_BUFFER_SIZE]; - sprintf(jmpcmd, "jumptotime %d", iPos/1000); - return (ac_exec(jmpcmd) == AC_ERR_NOERROR); -} -bool KviAmipInterface::hide() -{ - HWND hWinamp = (HWND)eval_int("var_phwnd"); - if(hWinamp && hWinamp != (HWND)-1) - { - ShowWindow(hWinamp, SW_HIDE); - return true; - } - return false; -} - -bool KviAmipInterface::show() -{ - HWND hWinamp = (HWND)eval_int("var_phwnd"); - if(hWinamp && hWinamp != (HWND)-1) - { - ShowWindow(hWinamp, SW_SHOW); - return true; - } - return false; -} - -bool KviAmipInterface::minimize() -{ - if(!amip_dll) return false; - return (ac_exec("control mimimize") == AC_ERR_NOERROR); -} - -bool KviAmipInterface::setPlayListPos(kvs_int_t &iPos) -{ - if(!amip_dll) return false; - char jmpcmd[AC_BUFFER_SIZE]; - sprintf(jmpcmd, "setplpos %d", iPos + 1); - return (ac_exec(jmpcmd) == AC_ERR_NOERROR); -} - -int KviAmipInterface::getPlayListPos() -{ - return eval_int("var_pos"); -} - -int KviAmipInterface::getListLength() -{ - return eval_int("var_ll"); -} - -bool KviAmipInterface::getRepeat() -{ - return eval_str("var_repeat").startsWith("on"); -} - -bool KviAmipInterface::getShuffle() -{ - return eval_str("var_shuffle").startsWith("on"); -} - -bool KviAmipInterface::setShuffle(bool &bVal) -{ - if(!amip_dll) return false; - bool res; - if (bVal) - res = (ac_exec("setshuffle on") == AC_ERR_NOERROR); - else - res = (ac_exec("setshuffle off") == AC_ERR_NOERROR); - return res; -} - -bool KviAmipInterface::setRepeat(bool &bVal) -{ - if(!amip_dll) return false; - bool res; - if (bVal) - res = (ac_exec("setrepeat on") == AC_ERR_NOERROR); - else - res = (ac_exec("setrepeat off") == AC_ERR_NOERROR); - return res; -} - -bool KviAmipInterface::amipExec(const QString &cmd) -{ - if(!amip_dll) return false; - QTextCodec *c=mediaplayer_get_codec(); - KviCString szCmd = c ? c->fromUnicode(cmd) : cmd.toUtf8(); - return (ac_exec(szCmd) == AC_ERR_NOERROR); -} - -QString KviAmipInterface::amipEval(const QString &cmd) -{ - QString ret; - if(!amip_dll) return ret; - QTextCodec *c=mediaplayer_get_codec(); - KviCString szCmd = c ? c->fromUnicode(cmd) : cmd.toUtf8(); - char buff[AC_BUFFER_SIZE]; - if((ac_eval(szCmd, buff) == AC_ERR_NOERROR)) { - QString s = buff; - QTextCodec *c=mediaplayer_get_codec(); - if (c) ret = c->toUnicode(s.toAscii()); - else ret=s; - } - return ret; -} - -#endif //COMPILE_ON_WINDOWS diff --git a/src/modules/mediaplayer/mp_amipinterface.h b/src/modules/mediaplayer/mp_amipinterface.h deleted file mode 100644 index f5eaf664d..000000000 --- a/src/modules/mediaplayer/mp_amipinterface.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef _MP_AMIPINTERFACE_H_ -#define _MP_AMIPINTERFACE_H_ -//============================================================================= -// -// File : mp_amipinterface.cpp -// Creation date : Sun 27 Mar 2005 16:55:09 by Szymon Stefanek -// -// This file is part of the KVIrc IRC client distribution -// Copyright (C) 2005-2010 Szymon Stefanek -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "kvi_settings.h" - -#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - - #include "mp_interface.h" - - class KviAmipInterface : public KviMediaPlayerInterface - { - public: - KviAmipInterface(); - ~KviAmipInterface(); - public: - virtual int detect(bool bStart); - virtual bool prev(); - virtual bool next(); - virtual bool play(); - virtual bool stop(); - virtual bool pause(); - virtual bool quit(); - virtual QString nowPlaying(); - virtual QString artist(); - virtual QString title(); - virtual QString genre(); - virtual QString comment(); - virtual QString album(); - virtual QString year(); - virtual QString mrl(); - virtual int position(); - virtual int length(); - virtual bool setVol(kvs_int_t &iVol); - virtual int getVol(); - virtual bool jumpTo(kvs_int_t &iPos); - virtual int sampleRate(); - virtual int bitRate(); - virtual int channels(); - virtual bool hide(); - virtual bool show(); - virtual bool minimize(); - virtual int getPlayListPos(); - virtual bool setPlayListPos(kvs_int_t &iPos); - virtual int getListLength(); - virtual bool getRepeat(); - virtual bool getShuffle(); - virtual bool setRepeat(bool &bVal); - virtual bool setShuffle(bool &bVal); - virtual bool amipExec(const QString &cmd); - virtual QString amipEval(const QString &cmd); - virtual KviMediaPlayerInterface::PlayerStatus status(); - }; - - MP_DECLARE_DESCRIPTOR(KviAmipInterface) - -#endif //COMPILE_ON_WINDOWS - -#endif //!_MP_AMIPINTERFACE_H_ diff --git a/src/modules/mediaplayer/mp_interface.cpp b/src/modules/mediaplayer/mp_interface.cpp deleted file mode 100644 index 3993ff8e6..000000000 --- a/src/modules/mediaplayer/mp_interface.cpp +++ /dev/null @@ -1,275 +0,0 @@ -//============================================================================= -// -// File : mp_interface.cpp -// Creation date : Fri Mar 25 20:01:25 2005 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2005-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "mp_interface.h" -#include "mp_mp3.h" - -#include "KviOptions.h" -#include "KviLocale.h" - -#include - -static QTextCodec * mediaplayer_get_codec() -{ - QTextCodec * c= QTextCodec::codecForName(KVI_OPTION_STRING(KviOption_stringWinampTextEncoding).toUtf8().data()); - if(!c)c = QTextCodec::codecForLocale(); - return c; - -} - -void KviMediaPlayerInterface::notImplemented() -{ - setLastError(__tr2qs_ctx("Function not implemented","mediaplayer")); -} - -int KviMediaPlayerInterface::position() -{ - notImplemented(); - return -1; -} - -int KviMediaPlayerInterface::length() -{ - notImplemented(); - return -1; -} - -bool KviMediaPlayerInterface::quit() -{ - notImplemented(); - return false; -} - -bool KviMediaPlayerInterface::hide() -{ - notImplemented(); - return false; -} - -bool KviMediaPlayerInterface::show() -{ - notImplemented(); - return false; -} - -bool KviMediaPlayerInterface::minimize() -{ - notImplemented(); - return false; -} - -QString KviMediaPlayerInterface::getLocalFile() -{ - QString ret = mrl(); - if(ret.isEmpty())return ret; - if(ret.startsWith("file://",Qt::CaseInsensitive)) - { - ret.remove(0,7); - return ret; - } - return QString(); -} - -QString KviMediaPlayerInterface::amipEval(const QString &) -{ - return QString(); -} - -#define SCAN_MP3_FILE \ - QString f = getLocalFile(); \ - if(f.isEmpty())return QString(); \ - mp3info mp3; \ - if(!scan_mp3_file(f,&mp3))return QString(); \ - QTextCodec *pCodec; \ - pCodec=mediaplayer_get_codec(); - -#define SCAN_MP3_FILE_RET_INT \ - QString f = getLocalFile(); \ - if(f.isEmpty())return -1; \ - mp3info mp3; \ - if(!scan_mp3_file(f,&mp3))return -1; - - -QString KviMediaPlayerInterface::artist() -{ - SCAN_MP3_FILE - return pCodec->toUnicode(QByteArray(mp3.id3.artist)); -} - -QString KviMediaPlayerInterface::title() -{ - SCAN_MP3_FILE - return pCodec->toUnicode(QByteArray(mp3.id3.title)); -} - -QString KviMediaPlayerInterface::genre() -{ - SCAN_MP3_FILE - return pCodec->toUnicode(QByteArray(get_typegenre(mp3.id3.genre[0]))); -} - -QString KviMediaPlayerInterface::comment() -{ - SCAN_MP3_FILE - return pCodec->toUnicode(QByteArray(mp3.id3.comment)); -} - -QString KviMediaPlayerInterface::year() -{ - SCAN_MP3_FILE - return QString(mp3.id3.year); -} - -QString KviMediaPlayerInterface::album() -{ - SCAN_MP3_FILE - return pCodec->toUnicode(QByteArray(mp3.id3.album)); -} - -bool KviMediaPlayerInterface::playMrl(const QString &) -{ - notImplemented(); - return false; -} - -bool KviMediaPlayerInterface::amipExec(const QString &) -{ - notImplemented(); - return false; -} - -bool KviMediaPlayerInterface::setVol(kvs_int_t &) -{ - notImplemented(); - return false; -} - -int KviMediaPlayerInterface::getVol() -{ - notImplemented(); - return -1; -} - -bool KviMediaPlayerInterface::mute() -{ - notImplemented(); - return false; -} - -bool KviMediaPlayerInterface::jumpTo(kvs_int_t &) -{ - notImplemented(); - return false; -} - -KviMediaPlayerInterface::PlayerStatus KviMediaPlayerInterface::status() -{ - notImplemented(); - return KviMediaPlayerInterface::Unknown; -} - -int KviMediaPlayerInterface::bitRate() -{ - SCAN_MP3_FILE_RET_INT - return header_bitrate(&(mp3.header)); -} - -int KviMediaPlayerInterface::sampleRate() -{ - SCAN_MP3_FILE_RET_INT - return header_frequency(&(mp3.header)); -} - -int KviMediaPlayerInterface::channels() -{ - SCAN_MP3_FILE_RET_INT - return header_channels(&(mp3.header)); -} - -int KviMediaPlayerInterface::getPlayListPos() -{ - notImplemented(); - return -1; -} - -bool KviMediaPlayerInterface::setPlayListPos(kvs_int_t &) -{ - notImplemented(); - return false; -} - -int KviMediaPlayerInterface::getListLength() -{ - notImplemented(); - return -1; -} - -int KviMediaPlayerInterface::getEqData(kvs_int_t &) -{ - notImplemented(); - return -1; -} - -bool KviMediaPlayerInterface::setEqData(kvs_int_t &, kvs_int_t &) -{ - notImplemented(); - return false; -} - -bool KviMediaPlayerInterface::getRepeat() -{ - notImplemented(); - return false; -} - -bool KviMediaPlayerInterface::getShuffle() -{ - notImplemented(); - return false; -} - -bool KviMediaPlayerInterface::setRepeat(bool &) -{ - notImplemented(); - return false; -} - -bool KviMediaPlayerInterface::setShuffle(bool &) -{ - notImplemented(); - return false; -} - -QString KviMediaPlayerInterface::mediaType() -{ - QString ret = mrl(); - if(ret.endsWith(".mp3",Qt::CaseInsensitive))ret = "MPEG Layer 3"; - else if(ret.endsWith(".ogg",Qt::CaseInsensitive))ret = "OGG Vorbis"; - else if(ret.endsWith(".avi",Qt::CaseInsensitive))ret = "Audio Video Interleave"; - else if(ret.endsWith(".mpeg",Qt::CaseInsensitive))ret = "MPEG Video"; - else if(ret.endsWith(".mpg",Qt::CaseInsensitive))ret = "MPEG Video"; - else if(ret.startsWith("http://",Qt::CaseInsensitive))ret = "HTTP Audio Stream"; - else ret = QString(); - return ret; -} diff --git a/src/modules/mediaplayer/mp_interface.h b/src/modules/mediaplayer/mp_interface.h deleted file mode 100644 index 61cd53d47..000000000 --- a/src/modules/mediaplayer/mp_interface.h +++ /dev/null @@ -1,238 +0,0 @@ -#ifndef _MP_INTERFACE_H_ -#define _MP_INTERFACE_H_ -//============================================================================= -// -// File : mp_interface.h -// Creation date : Fri Mar 25 20:01:25 2005 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2005-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "kvi_settings.h" -#include "KviQString.h" -#include "KviKvsTypes.h" - -class KviMediaPlayerInterface -{ -public: - // don't do any initialization in the constructor - // implement lazy initialization in each function instead - KviMediaPlayerInterface(){}; - virtual ~KviMediaPlayerInterface(){}; -protected: - QString m_szLastError; -public: - const QString & lastError() const { return m_szLastError; }; - - // - // mandatory interface - // - - // This should attempt to detect if the player is available on the user's system - // and returning a score from 0 to 100 depending on how likely the player will work - // and how many of its functions are available. 100 means that the interface - // is absolutely sure that the player will start and play stuff. - // If bStart is true then the function is allowed to explicitly start the player, - // otherwise a startup attempt should not be made and different methods should be used. - // This function is used for auto-detection and is called twice: the first time - // with bStart set to false to determine the players that potentially could run. - // If no player returns a reasonably high value by just guessing, then - // a second loop may be attempted with the "bStart" parameter set to true. - // A level of 0 is considered total failure: in this case detect() should - // also set the last error to a descriptive string. - virtual int detect(bool bStart) = 0; - - // play previous media, return false only on communication failure - virtual bool prev() = 0; - // play next media, return false only on communication failure - virtual bool next() = 0; - // start playback now, return false only on communication failure (i.e. return true when already playing) - virtual bool play() = 0; - // stop playback now, return false only on communication failure (i.e. return true when already stopped) - virtual bool stop() = 0; - // pause playback now (do NOT toggle pause, just pause), return false only on communication failure - virtual bool pause() = 0; - - // current media related - - // currently played media: it should include AT least the title - // but may also include other information. - // this string MUST be non-empty when the player is playing something. - // If it is empty then either the player is not playing or there are - // communication errors. - virtual QString nowPlaying() = 0; - // currently played media resource locator - // file:// for local files, dvb:// for dvb media, dvd:// for dvd's - // http:// for audio streams etc... - // empty if player is not playing (or in the tragic case that the player - // can't determine the url). - virtual QString mrl() = 0; - - // optional interface - - // this should play the specified mrl - // the mrl may be (or may be not) added to the player's playlist - // the function should return false if the player doesn't support - // this function or there is a communication error - virtual bool playMrl(const QString &mrl); - // what is this ? :D - virtual bool amipExec(const QString &cmd); - virtual QString amipEval(const QString &cmd); - // this is functions to hide,show and minimize the player interface - virtual bool hide(); - virtual bool show(); - virtual bool minimize(); - // set the volume of mediaplayer (0-255) - virtual bool setVol(kvs_int_t &iVol); - // get the pvolume value(0-255) - virtual int getVol(); - //mute the volume - virtual bool mute(); - // should quit the player if it's running - // return false only on communication failure - virtual bool quit(); - // return the current player status - enum PlayerStatus { Unknown, Stopped, Playing, Paused }; - virtual KviMediaPlayerInterface::PlayerStatus status(); - // current position in the media (msecs) - // 0 if the player isn't playing anything and -1 if unknown - virtual int position(); - // total length of the media (msecs) - // 0 if the player isn't playing anyting and -1 if unknown (e.g. a stream) - virtual int length(); - // jump to position - virtual bool jumpTo(kvs_int_t &iPos); - // interface with a default implementation for certain types of media (read for mp3) - // reimplement only if the player knows better - - // currently played media title (it's player choice if the title - // is to be derived from the media file name or from the information - // stored inside the file like the ID3 tag...) - // If the player is not playing, the returned string should be empty - virtual QString title(); - // currently played media artist's name - // If the player is not playing, the returned string should be empty - // If the player can't guess the artist it should return the string "unknown" - virtual QString artist(); - // currently plaued media genre - // If the player is not playing, the returned string should be empty - // If the player can't guess the genre it should return the string "unknown" - virtual QString genre(); - // currently played media comment. - // Empty string if the player isn't playing anything or there is no comment - virtual QString comment(); - // currently played media year - // Empty string if the player isn't playing anything or the year is unknown - virtual QString year(); - // currently played media album - // Empty string if the player isn't playing anything - // If the player can't guess the album/collection then this string should be "unknown" - virtual QString album(); - // bit rate in bits/sec, 0 if unknown - virtual int bitRate(); - // sample rate in samples/sec (Hz), 0 if unknown - virtual int sampleRate(); - // number of channels - virtual int channels(); - // frequency - // the type of the media (MPEG Layer 3, MPEG Layer 4, OGG Vorbis, AVI Stream etc..) - virtual QString mediaType(); - // get the position in the playlist - virtual int getPlayListPos(); - // set the position in the playlist - virtual bool setPlayListPos(kvs_int_t &iPos); - // return the list's length - virtual int getListLength(); - // return the Eq(number) value - virtual int getEqData(kvs_int_t &i_val); - // set the Eq(iPos) to Eq(iVal) value - virtual bool setEqData(kvs_int_t &iPos, kvs_int_t &iVal); - // get the Repeat bool value - virtual bool getRepeat(); - // get the shuffle bool value - virtual bool getShuffle(); - // set the Repeat bool value - virtual bool setRepeat(bool &bVal); - // set the shuffle bool value - virtual bool setShuffle(bool &bVal); - void setLastError(const QString &szLastError){ m_szLastError = szLastError; }; -protected: - void notImplemented(); - QString getLocalFile(); -}; - - -class KviMediaPlayerInterfaceDescriptor -{ -public: - KviMediaPlayerInterfaceDescriptor(){}; - virtual ~KviMediaPlayerInterfaceDescriptor(){}; -public: - virtual const QString & name() = 0; - virtual const QString & description() = 0; - virtual KviMediaPlayerInterface * instance() = 0; -}; - - -#define MP_DECLARE_DESCRIPTOR(_interfaceclass) \ - class _interfaceclass ## Descriptor : public KviMediaPlayerInterfaceDescriptor \ - { \ - public: \ - _interfaceclass ## Descriptor(); \ - virtual ~_interfaceclass ## Descriptor(); \ - protected: \ - _interfaceclass * m_pInstance; \ - QString m_szName; \ - QString m_szDescription; \ - public: \ - virtual const QString & name(); \ - virtual const QString & description(); \ - virtual KviMediaPlayerInterface * instance(); \ - }; - -#define MP_IMPLEMENT_DESCRIPTOR(_interfaceclass,_name,_description) \ - _interfaceclass ## Descriptor::_interfaceclass ## Descriptor() \ - : KviMediaPlayerInterfaceDescriptor() \ - { \ - m_pInstance = 0; \ - m_szName = _name; \ - m_szDescription = _description; \ - } \ - _interfaceclass ## Descriptor::~_interfaceclass ## Descriptor() \ - { \ - if(m_pInstance)delete m_pInstance; \ - } \ - const QString & _interfaceclass ## Descriptor::name() \ - { \ - return m_szName; \ - } \ - const QString & _interfaceclass ## Descriptor::description() \ - { \ - return m_szDescription; \ - } \ - KviMediaPlayerInterface * _interfaceclass ## Descriptor::instance() \ - { \ - if(!m_pInstance)m_pInstance = new _interfaceclass(); \ - return m_pInstance; \ - } - -#define MP_CREATE_DESCRIPTOR(_interfaceclass) \ - new _interfaceclass ## Descriptor() - -#endif //!_MP_INTERFACE_H_ diff --git a/src/modules/mediaplayer/mp_mp3.cpp b/src/modules/mediaplayer/mp_mp3.cpp deleted file mode 100644 index efdc0b473..000000000 --- a/src/modules/mediaplayer/mp_mp3.cpp +++ /dev/null @@ -1,458 +0,0 @@ -//============================================================================= -// -// File : mp_mp3.cpp -// Creation date : Fri Mar 25 20:01:25 2005 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2005-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// This file is based on the mp3tech.c. It is released under the original -// license and the original copyright notice follows. -// -// mp3tech.c -// -// Copyright (C) 2000 Cedric Tefft -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software Foundation -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// This file is based in part on: -// -// * MP3Info 0.5 by Ricardo Cerqueira -// * MP3Stat 0.9 by Ed Sweetman and -// Johannes Overmann -// -// There has been also a remarkable work by Cristopher Tieckle (Crissi) -// -//============================================================================= - -#include "mp_mp3.h" -#include "KviOptions.h" - -#include -#include - -#define MAXGENRE 147 -#define GENREROWS 50 - -/* - The Information is stored in the last 128 bytes of an MP3. The Tag - has got the following fields, and the offsets given here, are from - 0-127. - - Field Length Offsets - Tag 3 0-2 - Songname 30 3-32 - Artist 30 33-62 - Album 30 63-92 - Year 4 93-96 - Comment 30 97-126 - Genre 1 127 - - - The string-fields contain ASCII-data, coded in ISO-Latin 1 codepage. - Strings which are smaller than the field length are padded with zero- - bytes. - - Tag: The tag is valid if this field contains the string "TAG". This - has to be uppercase! - - Songname: This field contains the title of the MP3 (string as - above). - - Artist: This field contains the artist of the MP3 (string as above). - - Album: this field contains the album where the MP3 comes from - (string as above). - - Year: this field contains the year when this song has originally - been released (string as above). - - Comment: this field contains a comment for the MP3 (string as - above). Revision to this field has been made in ID3v1.1. See - A.4. - - Genre: this byte contains the offset of a genre in a predefined - list the byte is treated as an unsigned byte. The offset is - starting from 0. See A.3. -*/ - - -const char *typegenre [MAXGENRE+2] = -{ - "Blues","Classic Rock","Country","Dance","Disco","Funk","Grunge", - "Hip-Hop","Jazz","Metal","New Age","Oldies","Other","Pop","R&B", - "Rap","Reggae","Rock","Techno","Industrial","Alternative","Ska", - "Death Metal","Pranks","Soundtrack","Euro-Techno","Ambient", - "Trip-Hop","Vocal","Jazz+Funk","Fusion","Trance","Classical", - "Instrumental","Acid","House","Game","Sound Clip","Gospel","Noise", - "Alt. Rock","Bass","Soul","Punk","Space","Meditative", - "Instrumental Pop","Instrumental Rock","Ethnic","Gothic", - "Darkwave","Techno-Industrial","Electronic","Pop-Folk","Eurodance", - "Dream","Southern Rock","Comedy","Cult","Gangsta Rap","Top 40", - "Christian Rap","Pop/Funk","Jungle","Native American","Cabaret", - "New Wave","Psychedelic","Rave","Showtunes","Trailer","Lo-Fi", - "Tribal","Acid Punk","Acid Jazz","Polka","Retro","Musical", - "Rock & Roll","Hard Rock","Folk","Folk/Rock","National Folk", - "Swing","Fast-Fusion","Bebob","Latin","Revival","Celtic", - "Bluegrass","Avantgarde","Gothic Rock","Progressive Rock", - "Psychedelic Rock","Symphonic Rock","Slow Rock","Big Band", - "Chorus","Easy Listening","Acoustic","Humour","Speech","Chanson", - "Opera","Chamber Music","Sonata","Symphony","Booty Bass","Primus", - "Porn Groove","Satire","Slow Jam","Club","Tango","Samba", - "Folklore","Ballad","Power Ballad","Rhythmic Soul","Freestyle", - "Duet","Punk Rock","Drum Solo","A Cappella","Euro-House", - "Dance Hall","Goa","Drum & Bass","Club-House","Hardcore","Terror", - "Indie","BritPop","Negerpunk","Polsk Punk","Beat", - "Christian Gangsta Rap","Heavy Metal","Black Metal","Crossover", - "Contemporary Christian","Christian Rock","Merengue","Salsa", - "Thrash Metal","Anime","JPop","Synthpop","" -}; - -const char * get_typegenre(int idx) -{ - if(idx > MAXGENRE)return typegenre[12]; - return typegenre[idx]; -} - -int galphagenreindex[MAXGENRE+2] = -{ - 148,123,74,73,34,99,40,20,26,145,90, - 116,41,135,85,96,138,89,0,107,132,65,88, - 104,102,97,136,61,141,1,32,128,112,57,140, - 2,139,58,125,3,50,22,4,55,127,122,120, - 98,52,48,124,25,54,84,81,115,80,119,5, - 30,36,59,126,38,91,49,6,79,129,137,7, - 35,100,131,19,46,47,33,146,29,8,63,86, - 71,45,142,9,77,82,64,133,10,66,39,11, - 103,12,75,134,53,62,13,109,117,23,108,92, - 93,67,121,43,14,15,68,16,76,87,118,78, - 17,143,114,110,69,21,111,95,105,42,37,24, - 56,44,101,83,94,106,147,113,51,18,130,144, - 60,70,31,72,27,28 -}; - -int *alphagenreindex=&(galphagenreindex[1]); - - -int layer_tab[4]= {0, 3, 2, 1}; - -int frequencies[3][4] = -{ - {22050,24000,16000,50000}, /* MPEG 2.0 */ - {44100,48000,32000,50000}, /* MPEG 1.0 */ - {11025,12000,8000,50000} /* MPEG 2.5 */ -}; - -int bitrate[2][3][14] = -{ - { /* MPEG 2.0 */ - {32,48,56,64,80,96,112,128,144,160,176,192,224,256}, /* layer 1 */ - {8,16,24,32,40,48,56,64,80,96,112,128,144,160}, /* layer 2 */ - {8,16,24,32,40,48,56,64,80,96,112,128,144,160} /* layer 3 */ - }, - { /* MPEG 1.0 */ - {32,64,96,128,160,192,224,256,288,320,352,384,416,448}, /* layer 1 */ - {32,48,56,64,80,96,112,128,160,192,224,256,320,384}, /* layer 2 */ - {32,40,48,56,64,80,96,112,128,160,192,224,256,320} /* layer 3 */ - } -}; - -int frame_size_index[] = {24000, 72000, 72000}; - -const char *mode_text[] = -{ - "Stereo", "Joint Stereo", "Dual Channel", "Mono" -}; - -const char *emphasis_text[] = -{ - "None", "50/15 Microseconds", "Reserved", "CCITT J 17" -}; - -void resetmp3infoStruct(mp3info *i) -{ - i->file=0; - i->datasize=0; - i->header_isvalid=0; - memset(&i->header,0,sizeof(i->header)); - i->id3_isvalid=0; - memset(&i->id3,0,sizeof(i->id3)); - i->vbr=0; - i->vbr_average=0; - i->seconds=0; - i->frames=0; - i->badframes=0; -} - -int get_mp3_info(mp3info *mp3) -{ -// mp3header header; - - QFile fi(mp3->filename); - mp3->datasize=fi.size();//filestat.st_size; - - get_id3(mp3); - - if(get_first_header(mp3,0L)) - { - int bitrate,counter=0; - int data_start=ftell(mp3->file); - int lastrate=15-mp3->header.bitrate; - while((counter < NUM_SAMPLES) && lastrate) - { - int sample_pos=(counter*(mp3->datasize/NUM_SAMPLES+1))+data_start; - if(get_first_header(mp3,sample_pos)) - { - bitrate=15-mp3->header.bitrate; - } else { - bitrate=-1; - } - - if(bitrate != lastrate) - { - mp3->vbr=1; - } - lastrate=bitrate; - counter++; - - } - mp3->frames=(mp3->datasize-data_start)/(frame_length(&mp3->header)); - mp3->seconds = (int)((float)(frame_length(&mp3->header)*mp3->frames)/ - (float)(header_bitrate(&mp3->header)*125)+0.5); - mp3->vbr_average = (float)header_bitrate(&mp3->header); - } - - return 0; -} - -int get_first_header(mp3info *mp3, long startpos) -{ - int k, l=0,c; - mp3header h, h2; - long valid_start=0; - - fseek(mp3->file,startpos,SEEK_SET); - while(1) - { - while((c=fgetc(mp3->file)) != 255 && (c != EOF)) {} - if(c == 255) - { - ungetc(c,mp3->file); - valid_start=ftell(mp3->file); - if((l=get_header(mp3->file,&h))) - { - fseek(mp3->file,l-FRAME_HEADER_SIZE,SEEK_CUR); - for(k=1; (k < MIN_CONSEC_GOOD_FRAMES) && (mp3->datasize-ftell(mp3->file) >= FRAME_HEADER_SIZE); k++) - { - if(!(l=get_header(mp3->file,&h2))) break; - if(!sameConstant(&h,&h2)) break; - fseek(mp3->file,l-FRAME_HEADER_SIZE,SEEK_CUR); - } - if(k == MIN_CONSEC_GOOD_FRAMES) - { - fseek(mp3->file,valid_start,SEEK_SET); - memcpy(&(mp3->header), &h2, sizeof(mp3header)); - mp3->header_isvalid = 1; - return 1; - } - } - } else { - return 0; - } - } - return 0; -} - - -// Get next MP3 frame header. -// Return codes: -// positive value = Frame Length of this header -// 0 = No, we did not retrieve a valid frame header - -int get_header(FILE *file,mp3header *header) -{ - unsigned char buffer[FRAME_HEADER_SIZE]; - int fl; - - if(fread(&buffer,FRAME_HEADER_SIZE,1,file)<1) - { - header->sync=0; - return 0; - } - header->sync=(((int)buffer[0]<<4) | ((int)(buffer[1]&0xE0)>>4)); - if(buffer[1] & 0x10) header->version=(buffer[1] >> 3) & 1; - else header->version=2; - header->layer=(buffer[1] >> 1) & 3; - if((header->sync != 0xFFE) || (header->layer != 1)) - { - header->sync=0; - return 0; - } - header->crc=buffer[1] & 1; - header->bitrate=(buffer[2] >> 4) & 0x0F; - header->freq=(buffer[2] >> 2) & 0x3; - header->padding=(buffer[2] >>1) & 0x1; - header->extension=(buffer[2]) & 0x1; - header->mode=(buffer[3] >> 6) & 0x3; - header->mode_extension=(buffer[3] >> 4) & 0x3; - header->copyright=(buffer[3] >> 3) & 0x1; - header->original=(buffer[3] >> 2) & 0x1; - header->emphasis=(buffer[3]) & 0x3; - - return ((fl=frame_length(header)) >= MIN_FRAME_SIZE ? fl : 0); -} - -int frame_length(mp3header *header) -{ - return header->sync == 0xFFE ? - (frame_size_index[3-header->layer]*((header->version&1)+1)* - header_bitrate(header)/header_frequency(header))+ - header->padding : 1; -} - -int header_layer(mp3header *h) -{ - return layer_tab[h->layer]; -} - -int header_bitrate(mp3header *h) -{ - if(h->bitrate > 0) - return bitrate[h->version & 1][3-h->layer][h->bitrate-1]; - else - return -1; // unknown -} - -int header_frequency(mp3header *h) -{ - return frequencies[h->version][h->freq]; -} - -const char *header_emphasis(mp3header *h) -{ - return emphasis_text[h->emphasis]; -} - -const char *header_mode(mp3header *h) -{ - return mode_text[h->mode]; -} - -int header_channels(mp3header * h) -{ - return h->mode == 3 ? 1 : 2; -} - -int header_crc(mp3header *h) -{ - return (!h->crc); -} - -int sameConstant(mp3header *h1, mp3header *h2) -{ - if((*(uint*)h1) == (*(uint*)h2)) return 1; - - if((h1->version == h2->version ) && - (h1->layer == h2->layer ) && - (h1->crc == h2->crc ) && - (h1->freq == h2->freq ) && - (h1->mode == h2->mode ) && - (h1->copyright == h2->copyright ) && - (h1->original == h2->original ) && - (h1->emphasis == h2->emphasis )) - return 1; - else return 0; -} - -int get_id3(mp3info *mp3) -{ - // this will read ID3v1 tags - int retcode=0; - char fbuf[4]; - - if(mp3->datasize >= 128) - { - if(fseek(mp3->file, -128, SEEK_END )) - { - retcode |= 4; - } else { - size_t dummy = fread(fbuf,1,3,mp3->file); fbuf[3] = '\0'; - mp3->id3.genre[0]=255; - - if(!strcmp((const char *)"TAG",(const char *)fbuf)) - { - mp3->id3_isvalid=1; - mp3->datasize -= 128; - fseek(mp3->file, -125, SEEK_END); - dummy = fread(mp3->id3.title,1,30,mp3->file); mp3->id3.title[30] = '\0'; - dummy = fread(mp3->id3.artist,1,30,mp3->file); mp3->id3.artist[30] = '\0'; - dummy = fread(mp3->id3.album,1,30,mp3->file); mp3->id3.album[30] = '\0'; - dummy = fread(mp3->id3.year,1,4,mp3->file); mp3->id3.year[4] = '\0'; - dummy = fread(mp3->id3.comment,1,30,mp3->file); mp3->id3.comment[30] = '\0'; - if(mp3->id3.comment[28] == '\0') - { - mp3->id3.track[0] = mp3->id3.comment[29]; - } - dummy = fread(mp3->id3.genre,1,1,mp3->file); - unpad(mp3->id3.title); - unpad(mp3->id3.artist); - unpad(mp3->id3.album); - unpad(mp3->id3.year); - unpad(mp3->id3.comment); - } - } - } - return retcode; -} - -char *pad(char *string, int length) -{ - int l; - - l=strlen(string); - while(lfilename = "text"; - i->file = fopen(QTextCodec::codecForLocale()->fromUnicode(i->filename).data(),"rb"); - if(!i->file)return false; - - get_mp3_info(i); - - fclose(i->file); - - return (i->id3_isvalid); -} diff --git a/src/modules/mediaplayer/mp_mp3.h b/src/modules/mediaplayer/mp_mp3.h deleted file mode 100644 index 80dbda85c..000000000 --- a/src/modules/mediaplayer/mp_mp3.h +++ /dev/null @@ -1,137 +0,0 @@ -//============================================================================= -// -// File : mp_mp3.h -// Creation date : Fri Mar 25 20:01:25 2005 GMT by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2005-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// This file is based on the mp3tech.h. It is released under the original -// license and the original copyright notice follows. -// -// mp3tech.hCO -// -// Copyright (C) 2000 Cedric Tefft -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software Foundation -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// This file is based in part on: -// -// * MP3Info 0.5 by Ricardo Cerqueira -// * MP3Stat 0.9 by Ed Sweetman and -// Johannes Overmann -// -// There has been also a remarkable work by Cristopher Tieckle (Crissi) -// -//============================================================================= - -// MIN_CONSEC_GOOD_FRAMES defines how many consecutive valid MP3 frames -// we need to see before we decide we are looking at a real MP3 file -#define MIN_CONSEC_GOOD_FRAMES 4 -#define FRAME_HEADER_SIZE 4 -#define MIN_FRAME_SIZE 21 -#define NUM_SAMPLES 4 -#define TEXT_FIELD_LEN 30 -#define INT_FIELD_LEN 4 - - -#include "kvi_settings.h" - -#include -#include -#include - -#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - #include -#else - #include - #include - #include - #include -#endif - - -enum VBR_REPORT { VBR_VARIABLE, VBR_AVERAGE, VBR_MEDIAN }; - -typedef struct { - unsigned int sync; - unsigned int version; - unsigned int layer; - unsigned int crc; - unsigned int bitrate; - unsigned int freq; - unsigned int padding; - unsigned int extension; - unsigned int mode; - unsigned int mode_extension; - unsigned int copyright; - unsigned int original; - unsigned int emphasis; -} mp3header; - -typedef struct { - char title[31]; - char artist[31]; - char album[31]; - char year[5]; - char comment[31]; - unsigned char track[1]; - unsigned char genre[1]; -} id3tag; - -typedef struct { - QString filename; - FILE *file; - unsigned int datasize; - int header_isvalid; - mp3header header; - int id3_isvalid; - id3tag id3; - int vbr; - float vbr_average; - int seconds; - int frames; - int badframes; -} mp3info; - -// mode field: -// 00 - Stereo -// 01 - Joint stereo (Stereo) -// 10 - Dual channel (2 mono channels) -// 11 - Single channel (Mono) - -bool scan_mp3_file(QString& szFileName,mp3info * i); - -void resetmp3infoStruct(mp3info *i); - -int header_channels(mp3header *h); -int header_frequency(mp3header *h); -const char *header_emphasis(mp3header *h); -const char *header_mode(mp3header *h); -int header_layer(mp3header *h); -int header_bitrate(mp3header *h); -double header_version(mp3header *h); -int header_crc(mp3header *h); -int get_header(FILE *file,mp3header *header); -int frame_length(mp3header *header); -int sameConstant(mp3header *h1, mp3header *h2); -int get_mp3_info(mp3info *mp3); -int get_id3(mp3info *mp3); -char *pad(char *string, int length); -char *unpad(char *string); -int get_first_header(mp3info *mp3,long startpos); -//void tagedit_curs(char *filename, int filenum, int fileoutof, id3tag *tag); -const char * get_typegenre(int idx); - diff --git a/src/modules/mediaplayer/mp_mprisinterface.cpp b/src/modules/mediaplayer/mp_mprisinterface.cpp deleted file mode 100644 index 3bc59730e..000000000 --- a/src/modules/mediaplayer/mp_mprisinterface.cpp +++ /dev/null @@ -1,579 +0,0 @@ -//============================================================================= -// -// File : mp_mprisinterface.cpp -// Creation date : Thu 06 Dec 2007 14:20:02 by Tomasz MoÅ„ -// -// This file is part of the KVIrc IRC client distribution -// Copyright (C) 2007-2009 Tomasz MoÅ„ -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "mp_mprisinterface.h" -#if (defined(COMPILE_DBUS_SUPPORT) && !defined(COMPILE_ON_WINDOWS) && !defined(COMPILE_ON_MAC) && !defined(COMPILE_ON_MINGW)) -#include "KviLocale.h" - -/* - according to MPRIS 1.0, GetStatus returns struct of 4 integers. - - First integer: 0 = Playing, 1 = Paused, 2 = Stopped. - Second interger: 0 = Playing linearly, 1 = Playing randomly. - Third integer: 0 = Go to the next element once the current has finished playing, 1 = Repeat the current element - Fourth integer: 0 = Stop playing once the last element has been played, 1 = Never give up playing -*/ - -struct MPRISPlayerStatus -{ - int Play; - int Random; - int RepeatCurrent; - int RepeatPlaylist; -}; -Q_DECLARE_METATYPE( MPRISPlayerStatus ) - -QDBusArgument &operator<<(QDBusArgument &argument, const MPRISPlayerStatus &status) -{ - argument.beginStructure(); - argument << status.Play << status.Random << status.RepeatCurrent << status.RepeatPlaylist; - argument.endStructure(); - return argument; -} - -const QDBusArgument &operator>>(const QDBusArgument &argument, MPRISPlayerStatus &status) -{ - argument.beginStructure(); - argument >> status.Play >> status.Random >> status.RepeatCurrent >> status.RepeatPlaylist; - argument.endStructure(); - return argument; -} - -KviMPRISInterface::KviMPRISInterface() -: KviMediaPlayerInterface() -{ - qDBusRegisterMetaType(); -} - -KviMPRISInterface::~KviMPRISInterface() -{ -} - -int KviMPRISInterface::detect(bool) -{ - QDBusReply reply = QDBusConnection::sessionBus().interface()->registeredServiceNames(); - if (!reply.isValid()) /* something fishy with dbus, it won't work */ - return 0; - - foreach (QString name, reply.value()) - if (name == m_szServiceName) /* player is running */ - return 100; - - return 1; /* dbus works, player may be closed */ -} - -#define MPRIS_SIMPLE_CALL(__path, __action) \ - QDBusInterface dbus_iface(m_szServiceName, __path, \ - "org.freedesktop.MediaPlayer", QDBusConnection::sessionBus()); \ - QDBusMessage reply = dbus_iface.call(QDBus::Block, __action); \ - if (reply.type() == QDBusMessage::ErrorMessage) { \ - QDBusError err = reply; \ - qDebug("Error: %s\n%s\n", qPrintable(err.name()), qPrintable(err.message())); \ - return FALSE; \ - } \ - return TRUE; - -bool KviMPRISInterface::prev() -{ - MPRIS_SIMPLE_CALL("/Player", "Prev") -} - -bool KviMPRISInterface::next() -{ - MPRIS_SIMPLE_CALL("/Player", "Next") -} - -bool KviMPRISInterface::play() -{ - MPRIS_SIMPLE_CALL("/Player", "Play") -} - -bool KviMPRISInterface::stop() -{ - MPRIS_SIMPLE_CALL("/Player", "Stop") -} - -bool KviMPRISInterface::pause() -{ - MPRIS_SIMPLE_CALL("/Player", "Pause") -} - -bool KviMPRISInterface::quit() -{ - MPRIS_SIMPLE_CALL("/", "Quit") -} - -#define MPRIS_CALL_METHOD(__method, __return_if_fail) \ - QDBusInterface dbus_iface(m_szServiceName, "/Player", \ - "org.freedesktop.MediaPlayer", QDBusConnection::sessionBus()); \ - QDBusMessage reply = dbus_iface.call(QDBus::Block, __method); \ - if (reply.type() == QDBusMessage::ErrorMessage) { \ - QDBusError err = reply; \ - qDebug("Error: %s\n%s\n", qPrintable(err.name()), qPrintable(err.message())); \ - return __return_if_fail; \ - } - -#define MPRIS_GET_METADATA_FIELD(__field, __return_type, __return_if_fail) \ - if (this->status() != KviMediaPlayerInterface::Playing) \ - return __return_if_fail; \ - MPRIS_CALL_METHOD("GetMetadata", __return_if_fail) \ - foreach (QVariant v, reply.arguments()) { \ - QDBusArgument arg = qvariant_cast(v); \ - QVariant v = qdbus_cast(arg); \ - if (v.userType() == QVariant::Map) { \ - const QVariantMap map = v.toMap(); \ - QVariantMap::ConstIterator it = map.find(__field); \ - if (it != map.end() && it.key() == __field) { \ - return it.value().value< __return_type >(); \ - } \ - } \ - } \ - return __return_if_fail; - -#define MPRIS_CALL_METHOD_WITH_ARG(__method, __arg, __return_if_fail) \ - QDBusInterface dbus_iface(m_szServiceName, "/Player", \ - "org.freedesktop.MediaPlayer", QDBusConnection::sessionBus()); \ - QDBusMessage reply = dbus_iface.call(QDBus::Block, __method, __arg); \ - if (reply.type() == QDBusMessage::ErrorMessage) { \ - QDBusError err = reply; \ - qDebug("Error: %s\n%s\n", qPrintable(err.name()), qPrintable(err.message())); \ - return __return_if_fail; \ - } - -KviMediaPlayerInterface::PlayerStatus KviMPRISInterface::status() -{ - MPRIS_CALL_METHOD("GetStatus", KviMediaPlayerInterface::Unknown) - - MPRISPlayerStatus status; - - if(reply.arguments().isEmpty()) - return KviMediaPlayerInterface::Unknown; - - status = qdbus_cast(reply.arguments().first()); - - switch (status.Play) { - case 0: return KviMediaPlayerInterface::Playing; - case 1: return KviMediaPlayerInterface::Paused; - case 2: return KviMediaPlayerInterface::Stopped; - default: return KviMediaPlayerInterface::Unknown; - } -} - -QString KviMPRISInterface::nowPlaying() -{ - if (this->status() != KviMediaPlayerInterface::Playing) - return ""; - - MPRIS_CALL_METHOD("GetMetadata", "") - - QString artist; - QString title; - foreach (QVariant v, reply.arguments()) { - QDBusArgument arg = qvariant_cast(v); - QVariant v = qdbus_cast(arg); - if (v.userType() == QVariant::Map) { - const QVariantMap map = v.toMap(); - QVariantMap::ConstIterator it = map.constBegin(); - for ( ; it != map.constEnd(); ++it) { /* maybe do some configureable formatting */ - if (it.key() == "artist") - artist = it.value().toString(); - else if (it.key() == "title") - title = it.value().toString(); - } - } - } - if (artist.length() && title.length()) - return artist + " - " + title; - else - return ""; -} - -QString KviMPRISInterface::mrl() -{ - MPRIS_CALL_METHOD("GetMetadata", "") - - foreach (QVariant v, reply.arguments()) { - QDBusArgument arg = qvariant_cast(v); - QVariant v = qdbus_cast(arg); - if (v.userType() == QVariant::Map) { - const QVariantMap map = v.toMap(); - QVariantMap::ConstIterator it = map.find("location"); - if (it != map.end() && it.key() == "location") { - return it.value().toString(); - } - } - } - return ""; -} - -QString KviMPRISInterface::title() -{ - MPRIS_GET_METADATA_FIELD("title", QString, "") -} - -QString KviMPRISInterface::artist() -{ - MPRIS_GET_METADATA_FIELD("artist", QString, "") -} - -QString KviMPRISInterface::genre() -{ - MPRIS_GET_METADATA_FIELD("genre", QString, "") -} - -QString KviMPRISInterface::comment() -{ - MPRIS_GET_METADATA_FIELD("comment", QString, "") -} - -QString KviMPRISInterface::year() -{ - MPRIS_GET_METADATA_FIELD("year", QString, "") -} - -QString KviMPRISInterface::album() -{ - MPRIS_GET_METADATA_FIELD("album", QString, "") -} - -int KviMPRISInterface::bitRate() -{ - MPRIS_GET_METADATA_FIELD("audio-bitrate", int, -1) -} - -int KviMPRISInterface::sampleRate() -{ - MPRIS_GET_METADATA_FIELD("audio-samplerate", int, -1) -} - -bool KviMPRISInterface::setVol(kvs_int_t &iVol) -{ - MPRIS_CALL_METHOD_WITH_ARG("VolumeSet", QVariant((int)(100*iVol/255)), false); - return true; -} - -int KviMPRISInterface::getVol() -{ - MPRIS_CALL_METHOD("VolumeGet", -1) - - int iVol = reply.arguments().first().toInt(); - return iVol * 255 /100; -} - -int KviMPRISInterface::position() -{ - MPRIS_CALL_METHOD("PositionGet", -1) - return reply.arguments().first().toInt(); -} - -int KviMPRISInterface::length() -{ - MPRIS_CALL_METHOD("GetMetadata", -1) - - foreach (QVariant v, reply.arguments()) { - QDBusArgument arg = qvariant_cast(v); - QVariant v = qdbus_cast(arg); - if (v.userType() == QVariant::Map) { - const QVariantMap map = v.toMap(); - QVariantMap::ConstIterator it = map.constBegin(); - for ( ; it != map.constEnd(); ++it) { - if (it.key() == "mtime") - return it.value().toInt(); - } - } - } - return -1; -} - -bool KviMPRISInterface::jumpTo(kvs_int_t &iPos) -{ - MPRIS_CALL_METHOD_WITH_ARG("PositionSet", QVariant((int)iPos), false) - return true; -} - -/* audacious interface */ -MP_IMPLEMENT_DESCRIPTOR( - KviAudaciousInterface, - "audacious", - __tr2qs_ctx( - "An interface to the popular audacious media player.\n" \ - "Download it from http://audacious-media-player.org\n" - , - "mediaplayer" - ) -) - -KviAudaciousInterface::KviAudaciousInterface() -: KviMPRISInterface() -{ - m_szServiceName = "org.mpris.audacious"; -} - -int KviAudaciousInterface::getPlayListPos() -{ - QDBusInterface dbus_iface("org.mpris.audacious", "/org/atheme/audacious", - "org.atheme.audacious", QDBusConnection::sessionBus()); - QDBusReply pos = dbus_iface.call(QDBus::Block, "Position"); - return pos; -} - - -bool KviAudaciousInterface::quit() -{ - if (KviMPRISInterface::quit()) - return TRUE; - - /* compability with older versions */ - MPRIS_SIMPLE_CALL("/Player", "Quit") -} - -QString KviAudaciousInterface::mrl() -{ - MPRIS_CALL_METHOD("GetMetadata", "") - - foreach (QVariant v, reply.arguments()) { - QDBusArgument arg = qvariant_cast(v); - QVariant v = qdbus_cast(arg); - if (v.userType() == QVariant::Map) { - const QVariantMap map = v.toMap(); - QVariantMap::ConstIterator it = map.find("location"); - if (it != map.end() && it.key() == "location") { - return it.value().toString(); - } - /* Some audacious versions send URI instead of location */ - it = map.find("URI"); - if (it != map.end() && it.key() == "URI") { - return it.value().toString(); - } - } - } - return ""; -} - -KviMediaPlayerInterface::PlayerStatus KviAudaciousInterface::status() -{ - KviMediaPlayerInterface::PlayerStatus status; - status = KviMPRISInterface::status(); - if (status != KviMediaPlayerInterface::Unknown) - return status; - - /* compability with older versions */ - QDBusInterface dbus_iface(m_szServiceName, "/Player", - "org.freedesktop.MediaPlayer", QDBusConnection::sessionBus()); - if (!dbus_iface.isValid()) - return KviMediaPlayerInterface::Unknown; - - QDBusMessage reply = dbus_iface.call(QDBus::Block, "GetStatus"); - - switch (reply.arguments().first().toInt()) { - case 0: return KviMediaPlayerInterface::Playing; - case 1: return KviMediaPlayerInterface::Paused; - case 2: return KviMediaPlayerInterface::Stopped; - default: return KviMediaPlayerInterface::Unknown; - } -} - -int KviAudaciousInterface::length() -{ - int length = KviMPRISInterface::length(); - if (length != -1) - return length; - - /* compability with older versions */ - MPRIS_CALL_METHOD("GetMetadata", -1) - - foreach (QVariant v, reply.arguments()) { - QDBusArgument arg = qvariant_cast(v); - QVariant v = qdbus_cast(arg); - if (v.userType() == QVariant::Map) { - const QVariantMap map = v.toMap(); - QVariantMap::ConstIterator it = map.constBegin(); - for ( ; it != map.constEnd(); ++it) { - if (it.key() == "length") - return it.value().toInt(); - } - } - } - return -1; -} - -#define AUDACIOUS_GET_TUPLE_FIELD(__field) \ - if (this->status() != KviMediaPlayerInterface::Playing) \ - return ""; \ - QDBusInterface dbus_iface("org.mpris.audacious", "/org/atheme/audacious", \ - "org.atheme.audacious", QDBusConnection::sessionBus()); \ - QList args; \ - args << (uint)this->getPlayListPos() << QString(__field); \ - QDBusReply reply = dbus_iface.callWithArgumentList(QDBus::Block, "SongTuple", args); \ - return reply.value().variant().toString(); \ - -QString KviAudaciousInterface::year() -{ - AUDACIOUS_GET_TUPLE_FIELD("year") -} - -QString KviAudaciousInterface::mediaType() -{ - AUDACIOUS_GET_TUPLE_FIELD("codec") -} - -/* BMPx interface */ -MP_IMPLEMENT_DESCRIPTOR( - KviBmpxInterface, - "bmpx", - __tr2qs_ctx( - "An interface to BMPx.\n" \ - "Download it from http://sourceforge.net/projects/beepmp\n" - , - "mediaplayer" - ) -) - -KviBmpxInterface::KviBmpxInterface() -: KviMPRISInterface() -{ - m_szServiceName = "org.mpris.bmp"; -} - -/* BMPx doesn't provide GetStatus method, always assume Playing status */ -KviMediaPlayerInterface::PlayerStatus KviBmpxInterface::status() -{ - return KviMediaPlayerInterface::Playing; -} - -/* Amarok2 interface */ -MP_IMPLEMENT_DESCRIPTOR( - KviAmarok2Interface, - "amarok2", - __tr2qs_ctx( - "An interface to Amarok2.\n" \ - "Download it from http://amarok.kde.org\n" - , - "mediaplayer" - ) -) - -KviAmarok2Interface::KviAmarok2Interface() -: KviMPRISInterface() -{ - m_szServiceName = "org.mpris.amarok"; -} - -/* Qmmp interface */ -MP_IMPLEMENT_DESCRIPTOR( - KviQmmpInterface, - "Qmmp", - __tr2qs_ctx( - "An interface to Qmmp.\n" \ - "Download it from http://qmmp.ylsoftware.com\n" - , - "mediaplayer" - ) -) - -KviQmmpInterface::KviQmmpInterface() -: KviMPRISInterface() -{ - m_szServiceName = "org.mpris.qmmp"; -} - -/* xmms2 interface */ -MP_IMPLEMENT_DESCRIPTOR( - KviXmms2Interface, - "xmms2", - __tr2qs_ctx( - "An interface to the Xmms2 media player.\n" \ - "Download it from http://xmms2.org\n", - "mediaplayer" - ) -) - -KviXmms2Interface::KviXmms2Interface() -: KviMPRISInterface() -{ - m_szServiceName = "org.mpris.xmms2"; -} - -/* mozilla songbird interface */ -MP_IMPLEMENT_DESCRIPTOR( - KviSongbirdInterface, - "songbird", - __tr2qs_ctx( - "An interface to the Mozilla Songbird media player.\n" \ - "Download it from http://www.getsongbird.com.\n" \ - "To use it you have to install also the MPRIS addon " \ - "available at http://addons.songbirdnest.com/addon/1626.\n", - "mediaplayer" - ) -) - -KviSongbirdInterface::KviSongbirdInterface() -: KviMPRISInterface() -{ - m_szServiceName = "org.mpris.songbird"; -} - -KviMediaPlayerInterface::PlayerStatus KviSongbirdInterface::status() -{ - return KviMediaPlayerInterface::Playing; -} - -/* Totem interface */ -MP_IMPLEMENT_DESCRIPTOR( - KviTotemInterface, - "totem", - __tr2qs_ctx( - "An interface to Totem.\n" \ - "Download it from http://projects.gnome.org/totem/\n" - , - "mediaplayer" - ) -) - -KviTotemInterface::KviTotemInterface() -: KviMPRISInterface() -{ - m_szServiceName = "org.mpris.Totem"; -} - -/* Vlc interface */ -MP_IMPLEMENT_DESCRIPTOR( - KviVlcInterface, - "vlc", - __tr2qs_ctx( - "An interface to Vlc.\n" \ - "Download it from http://www.videolan.org/\n" \ - "You need to manually enable the DBus control\n" \ - "interface in the Vlc preferences\n" \ - , - "mediaplayer" - ) -) - -KviVlcInterface::KviVlcInterface() -: KviMPRISInterface() -{ - m_szServiceName = "org.mpris.vlc"; -} -#endif //COMPILE_ON_WINDOWS diff --git a/src/modules/mediaplayer/mp_mprisinterface.h b/src/modules/mediaplayer/mp_mprisinterface.h deleted file mode 100644 index f86af3b27..000000000 --- a/src/modules/mediaplayer/mp_mprisinterface.h +++ /dev/null @@ -1,135 +0,0 @@ -#ifndef _MP_AUDACIOUSINTERFACE_H_ -#define _MP_AUDACIOUSINTERFACE_H_ -//============================================================================= -// -// File : mp_mprisinterface.h -// Creation date : Thu 06 Dec 2007 14:20:02 by Tomasz MoÅ„ -// -// This file is part of the KVIrc IRC client distribution -// Copyright (C) 2007-2009 Tomasz MoÅ„ -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "mp_interface.h" - -#include "kvi_settings.h" - -#if (defined(COMPILE_DBUS_SUPPORT) && !defined(COMPILE_ON_WINDOWS) && !defined(COMPILE_ON_MAC) && !defined(COMPILE_ON_MINGW)) - #include - - class KviMPRISInterface : public KviMediaPlayerInterface - { - public: - KviMPRISInterface(); - virtual ~KviMPRISInterface(); - public: - QString m_szServiceName; - virtual int detect(bool bStart); - virtual bool prev(); - virtual bool next(); - virtual bool play(); - virtual bool stop(); - virtual bool pause(); - virtual bool quit(); - virtual KviMediaPlayerInterface::PlayerStatus status(); - virtual QString nowPlaying(); - virtual QString mrl(); - virtual QString title(); - virtual QString artist(); - virtual QString genre(); - virtual QString comment(); - virtual QString year(); - virtual QString album(); - virtual int bitRate(); - virtual int sampleRate(); - virtual bool setVol(kvs_int_t &iVol); - virtual int getVol(); - virtual int position(); - virtual int length(); - virtual bool jumpTo(kvs_int_t &iPos); - }; - - class KviAudaciousInterface : public KviMPRISInterface - { - public: - KviAudaciousInterface(); - public: - virtual bool quit(); - virtual KviMediaPlayerInterface::PlayerStatus status(); - virtual QString mrl(); - virtual int length(); - - virtual int getPlayListPos(); - virtual QString year(); - virtual QString mediaType(); - }; - - class KviBmpxInterface : public KviMPRISInterface - { - public: - KviBmpxInterface(); - virtual KviMediaPlayerInterface::PlayerStatus status(); - }; - - class KviAmarok2Interface : public KviMPRISInterface - { - public: - KviAmarok2Interface(); - }; - - class KviQmmpInterface : public KviMPRISInterface - { - public: - KviQmmpInterface(); - }; - - class KviXmms2Interface : public KviMPRISInterface - { - public: - KviXmms2Interface(); - }; - - class KviSongbirdInterface : public KviMPRISInterface - { - public: - KviSongbirdInterface(); - virtual KviMediaPlayerInterface::PlayerStatus status(); - }; - - class KviTotemInterface : public KviMPRISInterface - { - public: - KviTotemInterface(); - }; - - class KviVlcInterface : public KviMPRISInterface - { - public: - KviVlcInterface(); - }; - - MP_DECLARE_DESCRIPTOR(KviAudaciousInterface) - MP_DECLARE_DESCRIPTOR(KviBmpxInterface) - MP_DECLARE_DESCRIPTOR(KviAmarok2Interface) - MP_DECLARE_DESCRIPTOR(KviQmmpInterface) - MP_DECLARE_DESCRIPTOR(KviXmms2Interface) - MP_DECLARE_DESCRIPTOR(KviSongbirdInterface) - MP_DECLARE_DESCRIPTOR(KviTotemInterface) - MP_DECLARE_DESCRIPTOR(KviVlcInterface) -#endif //COMPILE_ON_WINDOWS - -#endif //_MP_AUDACIOUSINTERFACE_H_ diff --git a/src/modules/mediaplayer/mp_winampinterface.cpp b/src/modules/mediaplayer/mp_winampinterface.cpp deleted file mode 100644 index b52f37550..000000000 --- a/src/modules/mediaplayer/mp_winampinterface.cpp +++ /dev/null @@ -1,570 +0,0 @@ -//============================================================================= -// -// File : mp_winampinterface.cpp -// Creation date : Mon 28 Mar 2005 23:41:50 by Szymon Stefanek -// -// This file is part of the KVIrc IRC client distribution -// Copyright (C) 2005-2010 Szymon Stefanek -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "mp_winampinterface.h" -#include "KviOptions.h" - -#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - -#include - -#include "KviLocale.h" -#include "KviModule.h" - -#include - -#define IPC_STARTPLAY 102 -#define IPC_ISPLAYING 104 - -#define IPC_GETOUTPUTTIME 105 -// ** int res = SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETOUTPUTTIME); -// ** -// ** IPC_GETOUTPUTTIME returns the position in milliseconds of the -// ** current song (mode = 0), or the song length, in seconds (mode = 1). -// ** Returns -1 if not playing or error. - -#define IPC_JUMPTOTIME 106 -// ** SendMessage(hwnd_winamp,WM_WA_IPC,ms,IPC_JUMPTOTIME); -// ** IPC_JUMPTOTIME sets the position in milliseconds of the -// ** current song (approximately). - -#define IPC_SETPLAYLISTPOS 121 -// ** SendMessage(hwnd_winamp,WM_WA_IPC,position,IPC_SETPLAYLISTPOS) -// ** IPC_SETPLAYLISTPOS sets the playlsit position to 'position'. - -#define IPC_SETVOLUME 122 -// ** SendMessage(hwnd_winamp,WM_WA_IPC,volume,IPC_SETVOLUME); -// ** IPC_SETVOLUME sets the volume of Winamp (from 0-255). - -#define IPC_GETLISTLENGTH 124 -// ** int length = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTLENGTH); -// ** IPC_GETLISTLENGTH returns the length of the current playlist, in -// ** tracks. - -#define IPC_GETEQDATA 127 -// ** int data=SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA); -// ** IPC_GETEQDATA queries the status of the EQ. -// ** The value returned depends on what 'pos' is set to: -// ** Value Meaning -// ** ------------------ -// ** 0-9 The 10 bands of EQ data. 0-63 (+20db - -20db) -// ** 10 The preamp value. 0-63 (+20db - -20db) -// ** 11 Enabled. zero if disabled, nonzero if enabled. -// ** 12 Autoload. zero if disabled, nonzero if enabled. - -#define IPC_SETEQDATA 128 -// ** SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA); -// ** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SETEQDATA); -// ** IPC_SETEQDATA sets the value of the last position retrieved -// ** by IPC_GETEQDATA. This is pretty lame, and we should provide -// ** an extended version that lets you do a MAKELPARAM(pos,value). -// ** someday... - -#define IPC_GETPLAYLISTFILE 211 -// ** (requires Winamp 2.04+, only usable from plug-ins (not external apps)) -// ** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTFILE); -// ** IPC_GETPLAYLISTFILE gets the filename of the playlist entry [index]. -// ** returns a pointer to it. returns NULL on error. - -#define IPC_GETPLAYLISTTITLE 212 -// * (requires Winamp 2.04+, only usable from plug-ins (not external apps)) -// ** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTTITLE); -// ** IPC_GETPLAYLISTTITLE gets the title of the playlist entry [index]. -// ** returns a pointer to it. returns NULL on error. - -#define IPC_GET_SHUFFLE 250 -// ** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_SHUFFLE); -// ** -// ** IPC_GET_SHUFFLE returns the status of the Shuffle option (1 if set) - -#define IPC_GET_REPEAT 251 -// ** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_REPEAT); -// ** -// ** IPC_GET_REPEAT returns the status of the Repeat option (1 if set) - -#define IPC_SET_SHUFFLE 252 -// ** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_SHUFFLE); -// ** -// ** IPC_SET_SHUFFLE sets the status of the Shuffle option (1 to turn it on) - -#define IPC_SET_REPEAT 253 -// ** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_REPEAT); -// ** -// ** IPC_SET_REPEAT sets the status of the Repeat option (1 to turn it on) - -#define IPC_GETLISTPOS 125 -// ** int pos=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTPOS); -// ** IPC_GETLISTPOS returns the playlist position. A lot like IPC_WRITEPLAYLIST -// ** only faster since it doesn't have to write out the list. Heh, silly me. - -#define IPC_GETINFO 126 -// ** int inf=SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETINFO); -// ** IPC_GETINFO returns info about the current playing song. The value -// ** it returns depends on the value of 'mode'. -// ** Mode Meaning -// ** ------------------ -// ** 0 Samplerate (i.e. 44100) -// ** 1 Bitrate (i.e. 128) -// ** 2 Channels (i.e. 2) - -#define IPC_PLAYFILE 100 -// ** COPYDATASTRUCT cds; -// ** cds.dwData = IPC_PLAYFILE; -// ** cds.lpData = (void *) "file.mp3"; -// ** cds.cbData = strlen((char *) cds.lpData)+1; // include space for null char -// ** SendMessage(hwnd_winamp,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cds); -// ** -// ** This will play the file "file.mp3". - -#define IPC_ISPLAYING 104 -// ** int res = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISPLAYING); -// ** IPC_ISPLAYING returns the status of playback. -// ** If it returns 1, it is playing. if it returns 3, it is paused, -// ** if it returns 0, it is not playing. - -// The following stuff needs PostMessage(hwnd_winamp,WM_COMMAND,id,0); -#define WINAMP_BUTTON1 40044 -#define WINAMP_BUTTON2 40045 -#define WINAMP_BUTTON3 40046 -#define WINAMP_BUTTON4 40047 -#define WINAMP_BUTTON5 40048 - -#define WINAMP_CMD_PREV WINAMP_BUTTON1 -#define WINAMP_CMD_PLAY WINAMP_BUTTON2 -#define WINAMP_CMD_PAUSE WINAMP_BUTTON3 -#define WINAMP_CMD_STOP WINAMP_BUTTON4 -#define WINAMP_CMD_NEXT WINAMP_BUTTON5 - -#define WINAMP_CMD_QUIT 40001 - -#define KVIRC_WM_USER 63112 - -#define KVIRC_WM_USER_CHECK 13123 -#define KVIRC_WM_USER_CHECK_REPLY 13124 -#define KVIRC_WM_USER_GETTITLE 5000 -#define KVIRC_WM_USER_GETFILE 10000 -#define KVIRC_WM_USER_TRANSFER 15000 - - -static QTextCodec * mediaplayer_get_codec() -{ - QTextCodec * c= QTextCodec::codecForName(KVI_OPTION_STRING(KviOption_stringWinampTextEncoding).toAscii()); - if(!c)c = QTextCodec::codecForLocale(); - return c; - -} - -static HWND find_winamp(KviWinampInterface * i) -{ - HWND hWnd = FindWindow("Winamp v1.x",NULL); - if(!hWnd) - { - // try to start the process ? - i->setLastError(__tr2qs_ctx("Can't find a running winamp window","mediaplayer")); - } - return hWnd; -} - - -MP_IMPLEMENT_DESCRIPTOR( - KviWinampInterface, - "winamp", - __tr2qs_ctx( - "An interface to the popupar Winamp media player.\n" \ - "You can download it from http://www.winamp.com.\n" \ - "To use all the features of this interface you must " \ - "copy the gen_kvirc.dll plugin found in the KVIrc " \ - "distribution directory to the Winamp plugins folder " \ - "and restart winamp." - , - "mediaplayer" - ) -) - - -KviWinampInterface::KviWinampInterface() -: KviMediaPlayerInterface() -{ -} - -KviWinampInterface::~KviWinampInterface() -{ -} - - -int KviWinampInterface::detect(bool bStart) -{ - if(find_winamp(this))return 80; - // FIXME : check for Programs Folder\Winamp\Winamp.exe ? - // FIXME : if bStart try to start winamp.exe ? - return 50; -} - -#define MP_WINAMP_SENDMESSAGE(__cmdname,__wmmsg,__lparam,__wparam) \ - bool KviWinampInterface::__cmdname() \ - { \ - HWND hWinamp = find_winamp(this); \ - if(hWinamp)SendMessage(hWinamp,__wmmsg,__lparam,__wparam); \ - return hWinamp != 0; \ - } - -#define MP_WINAMP_WM_USER(__cmdname,_ipcmsg) MP_WINAMP_SENDMESSAGE(__cmdname,WM_USER,0,_ipcmsg) -#define MP_WINAMP_WM_COMMAND(__cmdname,_cmdmsg) MP_WINAMP_SENDMESSAGE(__cmdname,WM_COMMAND,_cmdmsg,0) - -MP_WINAMP_WM_USER(play,IPC_STARTPLAY) -MP_WINAMP_WM_COMMAND(stop,WINAMP_CMD_STOP) -MP_WINAMP_WM_COMMAND(next,WINAMP_CMD_NEXT) -MP_WINAMP_WM_COMMAND(prev,WINAMP_CMD_PREV) -MP_WINAMP_WM_COMMAND(pause,WINAMP_CMD_PAUSE) -MP_WINAMP_WM_COMMAND(quit,WINAMP_CMD_QUIT) - - -int KviWinampInterface::length() -{ - int leninsecs = -1; - HWND hWinamp = find_winamp(this); - if(hWinamp)leninsecs = SendMessage(hWinamp,WM_USER,1,IPC_GETOUTPUTTIME); - return leninsecs * 1000; -} - -int KviWinampInterface::position() -{ - int leninmsecs = -1; - HWND hWinamp = find_winamp(this); - if(hWinamp)leninmsecs = SendMessage(hWinamp,WM_USER,0,IPC_GETOUTPUTTIME); - return leninmsecs; -} - -int KviWinampInterface::bitRate() -{ - int ret = -1; - HWND hWinamp = find_winamp(this); - if(hWinamp)ret = SendMessage(hWinamp,WM_USER,1,IPC_GETINFO); - return ret; -} - -int KviWinampInterface::sampleRate() -{ - int ret = -1; - HWND hWinamp = find_winamp(this); - if(hWinamp)ret = SendMessage(hWinamp,WM_USER,0,IPC_GETINFO); - return ret; -} - -int KviWinampInterface::channels() -{ - int ret = -1; - HWND hWinamp = find_winamp(this); - if(hWinamp)ret = SendMessage(hWinamp,WM_USER,2,IPC_GETINFO); - return ret; -} - -KviMediaPlayerInterface::PlayerStatus KviWinampInterface::status() -{ - HWND hWinamp = find_winamp(this); - int ret = 1000; - if(hWinamp)ret = SendMessage(hWinamp,WM_USER,0,IPC_ISPLAYING); - switch(ret) - { - case 0: - return KviMediaPlayerInterface::Stopped; - break; - case 3: - return KviMediaPlayerInterface::Paused; - break; - case 1: - return KviMediaPlayerInterface::Playing; - break; - default: - return KviMediaPlayerInterface::Unknown; - break; - } - return KviMediaPlayerInterface::Unknown; -} - -QString KviWinampInterface::mrl() -{ - QString ret; - HWND hWinamp = find_winamp(this); - if(hWinamp) - { - int ret2 = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_CHECK); - - if(ret2 =! KVIRC_WM_USER_CHECK_REPLY) - { - setLastError(__tr2qs_ctx("The winamp plugin has not been installed properly. Check /help mediaplayer.nowplaying","mediaplayer")); - return ret; - } - - int len = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_GETFILE); - - if(len < 4096) - { - char szBuffer[4096]; - - for(int i = 0;i < len;i++) - { - szBuffer[i] = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_TRANSFER + i); - } - szBuffer[len] = '\0'; - QTextCodec *c=mediaplayer_get_codec(); - if (c) ret = c->toUnicode(szBuffer); - else ret=szBuffer; - if(!ret.startsWith("http://",Qt::CaseInsensitive)) - ret.prepend("file://"); - } - } - return ret; -} - -QString KviWinampInterface::nowPlaying() -{ - QString ret; - HWND hWinamp = find_winamp(this); - if(hWinamp) - { - int retpippo = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_CHECK); - if(retpippo =! KVIRC_WM_USER_CHECK_REPLY) - { - setLastError(__tr2qs_ctx("The winamp plugin has not been installed properly. Check /help mediaplayer.nowplaying","mediaplayer") ); - return ret; - } - - int len = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_GETTITLE); - - if(len < 4096) - { - char szBuffer[4096]; - - for(int i = 0;i < len;i++) - { - szBuffer[i] = SendMessage(hWinamp,WM_USER,KVIRC_WM_USER,KVIRC_WM_USER_TRANSFER + i); - } - szBuffer[ len ] = '\0'; - - QTextCodec *c=mediaplayer_get_codec(); - if (c) ret = c->toUnicode(szBuffer); - else ret=szBuffer; - } - } - return ret; -} - -bool KviWinampInterface::playMrl(const QString &mrl) -{ - HWND hWinamp = find_winamp(this); - if(hWinamp) - { - QTextCodec *c=mediaplayer_get_codec(); - KviCString szMrl = c ? c->fromUnicode(mrl) : mrl.toUtf8(); - COPYDATASTRUCT cds; - cds.dwData = IPC_PLAYFILE; - cds.lpData = (void *)szMrl.ptr(); - cds.cbData = szMrl.len() + 1; // include space for null char - SendMessage(hWinamp,WM_COPYDATA,(WPARAM)NULL,(LPARAM) &cds); - return true; - } - return false; -} - -bool KviWinampInterface::setVol(kvs_int_t &iVol) -{ - HWND hWinamp = find_winamp(this); - if(hWinamp) - { - SendMessage(hWinamp,WM_USER,iVol,IPC_SETVOLUME); - return true; - } - return false; -} - -int KviWinampInterface::getVol() -{ - int ret = -1; - HWND hWinamp = find_winamp(this); -#if defined(COMPILE_ON_MINGW) - if(hWinamp)ret = SendMessage(hWinamp,WM_USER,666,IPC_SETVOLUME); -#else - if(hWinamp)ret = SendMessage(hWinamp,WM_USER,-666,IPC_SETVOLUME); -#endif - return ret; -} - -bool KviWinampInterface::jumpTo(kvs_int_t &iPos) -{ - HWND hWinamp = find_winamp(this); - if(hWinamp) - { - SendMessage(hWinamp,WM_USER,iPos,IPC_JUMPTOTIME); - return true; - } - return false; -} -bool KviWinampInterface::hide() -{ - HWND hWinamp = find_winamp(this); - HWND hWinampPE = FindWindow("Winamp PE",NULL); /*Playlist*/ - HWND hWinampEQ = FindWindow("Winamp EQ",NULL); /*Equalizer*/ - HWND hWinampMB = FindWindow("Winamp MB",NULL); /*MiniBrowser*/ - HWND hWinampGen = FindWindow("Winamp Gen",NULL); /*Library*/ - HWND hWinampVideo = FindWindow("Winamp Video",NULL); /*Video*/ - if(hWinamp) - { - ShowWindow(hWinamp, SW_HIDE); - if(hWinampPE || hWinampEQ || hWinampMB || hWinampGen || hWinampVideo ) - { - if(hWinampPE) - ShowWindow(hWinampPE, SW_HIDE); - if(hWinampEQ) - ShowWindow(hWinampEQ, SW_HIDE); - if(hWinampMB) - ShowWindow(hWinampMB, SW_HIDE); - if(hWinampGen) - ShowWindow(hWinampGen, SW_HIDE); - if(hWinampVideo) - ShowWindow(hWinampVideo, SW_HIDE); - return true; - } - return true; - } - return false; -} - -bool KviWinampInterface::show() -{ - HWND hWinamp = find_winamp(this); - if(hWinamp) - { - ShowWindow(hWinamp, SW_SHOW); - return true; - } - return false; -} - -bool KviWinampInterface::minimize() -{ - HWND hWinamp = find_winamp(this); - if(hWinamp) - { - ShowWindow(hWinamp, SW_SHOWMINIMIZED); - return true; - } - return false; -} - -bool KviWinampInterface::setPlayListPos(kvs_int_t &iPos) -{ - HWND hWinamp = find_winamp(this); - if(hWinamp) - { - SendMessage(hWinamp,WM_USER,iPos,IPC_SETPLAYLISTPOS); - return true; - } - return false; -} - -int KviWinampInterface::getPlayListPos() -{ - int ret = -1; - HWND hWinamp = find_winamp(this); - if(hWinamp)ret = SendMessage(hWinamp,WM_USER,2,IPC_GETLISTPOS); - return ret; -} - -int KviWinampInterface::getListLength() -{ - int ret = -1; - HWND hWinamp = find_winamp(this); - if(hWinamp)ret = SendMessage(hWinamp,WM_USER,2,IPC_GETLISTLENGTH); - return ret; -} - -bool KviWinampInterface::setEqData(kvs_int_t &iPos, kvs_int_t &iVal) -{ - HWND hWinamp = find_winamp(this); - if(hWinamp) - { - SendMessage(hWinamp,WM_USER,iPos,IPC_GETEQDATA); - SendMessage(hWinamp,WM_USER,iVal,IPC_SETEQDATA); - return true; - } - return false; -} - -int KviWinampInterface::getEqData(kvs_int_t &ival) -{ - HWND hWinamp = find_winamp(this); - int ret = -1; - if(hWinamp) - { - ret = SendMessage(hWinamp,WM_USER,ival,IPC_GETEQDATA); - return ret; - } - return ret; -} - -bool KviWinampInterface::getRepeat() -{ - HWND hWinamp = find_winamp(this); - if(hWinamp) - { - bool bRepeat = SendMessage(hWinamp,WM_USER,0,IPC_GET_REPEAT); - return bRepeat; - } - return false; -} - -bool KviWinampInterface::getShuffle() -{ - HWND hWinamp = find_winamp(this); - if(hWinamp) - { - bool bShuffle = SendMessage(hWinamp,WM_USER,0,IPC_GET_SHUFFLE); - return bShuffle; - } - return false; -} - -bool KviWinampInterface::setShuffle(bool &bVal) -{ - HWND hWinamp = find_winamp(this); - if(hWinamp) - { - bool bRepeat = SendMessage(hWinamp,WM_USER,bVal,IPC_SET_SHUFFLE); - return bRepeat; - } - return false; -} - -bool KviWinampInterface::setRepeat(bool &bVal) -{ - HWND hWinamp = find_winamp(this); - if(hWinamp) - { - bool bShuffle = SendMessage(hWinamp,WM_USER,bVal,IPC_SET_REPEAT); - return bShuffle; - } - return false; -} -#endif //COMPILE_ON_WINDOWS diff --git a/src/modules/mediaplayer/mp_winampinterface.h b/src/modules/mediaplayer/mp_winampinterface.h deleted file mode 100644 index 648c3c581..000000000 --- a/src/modules/mediaplayer/mp_winampinterface.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef _MP_WINAMPINTERFACE_H_ -#define _MP_WINAMPINTERFACE_H_ -//============================================================================= -// -// File : mp_winampinterface.h -// Creation date : Mon 28 Mar 2005 23:41:50 by Szymon Stefanek -// -// This file is part of the KVIrc IRC client distribution -// Copyright (C) 2005-2010 Szymon Stefanek -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "kvi_settings.h" - -#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - - #include "mp_interface.h" - - class KviWinampInterface : public KviMediaPlayerInterface - { - public: - KviWinampInterface(); - ~KviWinampInterface(); - public: - virtual int detect(bool bStart); - virtual bool prev(); - virtual bool next(); - virtual bool play(); - virtual bool stop(); - virtual bool pause(); - virtual bool quit(); - virtual QString nowPlaying(); - virtual QString mrl(); - virtual int position(); - virtual int length(); - virtual bool playMrl(const QString &mrl); - virtual bool setVol(kvs_int_t &iVol); - virtual int getVol(); - virtual bool jumpTo(kvs_int_t &iPos); - virtual int sampleRate(); - virtual int bitRate(); - virtual int channels(); - virtual bool hide(); - virtual bool show(); - virtual bool minimize(); - virtual int getPlayListPos(); - virtual bool setPlayListPos(kvs_int_t &iPos); - virtual int getListLength(); - virtual int getEqData(kvs_int_t &ival); - virtual bool setEqData(kvs_int_t &iPos, kvs_int_t &iVal); - virtual bool getRepeat(); - virtual bool getShuffle(); - virtual bool setRepeat(bool &bVal); - virtual bool setShuffle(bool &bVal); - virtual KviMediaPlayerInterface::PlayerStatus status(); - }; - - MP_DECLARE_DESCRIPTOR(KviWinampInterface) - -#endif //COMPILE_ON_WINDOWS - -#endif //!_MP_WINAMPINTERFACE_H_ diff --git a/src/modules/mediaplayer/mp_xmmsinterface.cpp b/src/modules/mediaplayer/mp_xmmsinterface.cpp deleted file mode 100644 index 23eddf03b..000000000 --- a/src/modules/mediaplayer/mp_xmmsinterface.cpp +++ /dev/null @@ -1,358 +0,0 @@ -//============================================================================= -// -// File : mp_xmmsinterface.cpp -// Creation date : Fri 25 Mar 2005 20:04:54 by Szymon Stefanek -// -// This file is part of the KVIrc IRC client distribution -// Copyright (C) 2005-2010 Szymon Stefanek -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// Thnx to Alexander Stillich for Audacious -// media player interface hints :) -// -//============================================================================= - -#include "mp_xmmsinterface.h" - -#if (!defined(COMPILE_ON_WINDOWS) && !defined(COMPILE_ON_MAC) && !defined(COMPILE_ON_MINGW)) - -#include "KviLocale.h" - -MP_IMPLEMENT_DESCRIPTOR( - KviXmmsInterface, - "xmms", - __tr2qs_ctx( - "An interface to the popular UNIX xmms media player.\n" \ - "Download it from http://legacy.xmms2.org\n" - , - "mediaplayer" - ) -) - -MP_IMPLEMENT_DESCRIPTOR( - KviAudaciousClassicInterface, - "audacious classic", - __tr2qs_ctx( - "An interface to the popular UNIX audacious media player.\n" \ - "Download it from http://audacious-media-player.org\n" - , - "mediaplayer" - ) -) - -static const char *xmms_lib_names[] = -{ - "libxmms.so", - "libxmms.so.1", - "/usr/lib/libxmms.so", - "/usr/lib/libxmms.so.1", - "/usr/local/lib/libxmms.so", - "/usr/local/lib/libxmms.so.1", - 0 -}; - -static const char *audacious_lib_names[] = -{ - "libaudacious.so", - "libaudacious.so.4", - "/usr/lib/libaudacious.so", - "/usr/lib/libaudacious.so.4", - "/usr/local/lib/libaudacious.so", - "/usr/local/lib/libaudacious.so.4", - 0 -}; - - - -KviXmmsInterface::KviXmmsInterface() -: KviMediaPlayerInterface() -{ - m_pPlayerLibrary = 0; - m_szPlayerLibraryName = "libxmms.so"; - m_pLibraryPaths = xmms_lib_names; -} - -KviXmmsInterface::~KviXmmsInterface() -{ - if(m_pPlayerLibrary) - { - m_pPlayerLibrary->unload(); - delete m_pPlayerLibrary; - m_pPlayerLibrary = 0; - } -} - -KviAudaciousClassicInterface::KviAudaciousClassicInterface() -: KviXmmsInterface() -{ - m_szPlayerLibraryName = "libaudacious.so"; - m_pLibraryPaths = audacious_lib_names; -} - -KviAudaciousClassicInterface::~KviAudaciousClassicInterface() -{ -} - -bool KviXmmsInterface::loadPlayerLibrary() -{ - if(m_pPlayerLibrary && m_pPlayerLibrary->isLoaded())return true; - - const char **lib_name = m_pLibraryPaths; - while(*lib_name) - { - m_pPlayerLibrary = new QLibrary(*lib_name); - if(m_pPlayerLibrary->load()) - { - m_szPlayerLibraryName = *lib_name; - return true; - } - delete m_pPlayerLibrary; - m_pPlayerLibrary = 0; - lib_name++; - } - return false; -} - -void * KviXmmsInterface::lookupSymbol(const char * szSymbolName) -{ - if(!m_pPlayerLibrary) - { - if(!loadPlayerLibrary()) - { - QString tmp; - KviQString::sprintf(tmp,__tr2qs_ctx("Can't load the player library (%Q)","mediaplayer"),&m_szPlayerLibraryName); - setLastError(tmp); - return 0; - } - } - void * symptr =m_pPlayerLibrary->resolve(szSymbolName); - if(!symptr) - { - QString tmp; - KviQString::sprintf(tmp,__tr2qs_ctx("Can't find symbol %s in %Q","mediaplayer"),szSymbolName,&m_szPlayerLibraryName); - setLastError(tmp); - } - return symptr; -} - - -int KviXmmsInterface::detect(bool) -{ - void * sym = lookupSymbol("xmms_remote_play"); - return sym ? 80 : 0; -} - -#define XMMS_SIMPLE_CALL(__symname) \ - void (*sym)(int) = (void (*)(int))lookupSymbol(__symname); \ - if(!sym)return false; \ - sym(0); \ - return true; - -bool KviXmmsInterface::prev() -{ - XMMS_SIMPLE_CALL("xmms_remote_playlist_prev") -} - -bool KviXmmsInterface::next() -{ - XMMS_SIMPLE_CALL("xmms_remote_playlist_next") -} - -bool KviXmmsInterface::play() -{ - XMMS_SIMPLE_CALL("xmms_remote_play") -} - -bool KviXmmsInterface::stop() -{ - XMMS_SIMPLE_CALL("xmms_remote_stop") -} - -bool KviXmmsInterface::pause() -{ - XMMS_SIMPLE_CALL("xmms_remote_pause") -} - -bool KviXmmsInterface::quit() -{ - XMMS_SIMPLE_CALL("xmms_remote_quit") -} - -bool KviXmmsInterface::jumpTo(kvs_int_t &iPos) -{ - void (*sym)(int,int) = (void (*)(int,int))lookupSymbol("xmms_remote_jump_to_time"); - if(!sym)return false; - sym(0,iPos); - return true; -} - -bool KviXmmsInterface::setVol(kvs_int_t &iVol) -{ - void (*sym)(int,int) = (void (*)(int,int))lookupSymbol("xmms_remote_set_main_volume"); - if(!sym)return false; - sym(0,100*iVol/255); - return true; -} - -int KviXmmsInterface::getVol() -{ - int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_main_volume"); - if(!sym)return -1; - int iVol = sym(0); - return iVol * 255 /100; -} - -bool KviXmmsInterface::getRepeat() -{ - bool (*sym)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_repeat"); - if(!sym)return false; - bool ret = sym(0); - return ret; -} - -bool KviXmmsInterface::setRepeat(bool &bVal) -{ - bool (*sym1)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_repeat"); - if(!sym1)return false; - bool bNow = sym1(0); - if(bNow != bVal) - { - void (*sym2)(int) = (void (*)(int))lookupSymbol("xmms_remote_toggle_repeat"); - if(!sym2)return false; - sym2(0); - } - return true; -} - -bool KviXmmsInterface::getShuffle() -{ - bool (*sym)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_shuffle"); - if(!sym)return false; - bool ret = sym(0); - return ret; -} - -bool KviXmmsInterface::setShuffle(bool &bVal) -{ - bool (*sym1)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_shuffle"); - if(!sym1)return false; - bool bNow = sym1(0); - if(bNow != bVal) - { - void (*sym2)(int) = (void (*)(int))lookupSymbol("xmms_remote_toggle_shuffle"); - if(!sym2)return false; - sym2(0); - } - return true; -} - -KviMediaPlayerInterface::PlayerStatus KviXmmsInterface::status() -{ - bool (*sym1)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_paused"); - if(sym1) - { - if(sym1(0))return KviMediaPlayerInterface::Paused; - bool (*sym2)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_playing"); - if(sym2) - { - if(sym2(0))return KviMediaPlayerInterface::Playing; - else return KviMediaPlayerInterface::Stopped; - } - } - - return KviMediaPlayerInterface::Unknown; -} - -bool KviXmmsInterface::playMrl(const QString &mrl) -{ - void (*sym)(int,char *) = (void (*)(int,char *))lookupSymbol("xmms_remote_playlist_add_url_string"); - QByteArray tmp = mrl.toLocal8Bit(); - if(!tmp.isEmpty()) - { - if(sym) - { - sym(0,tmp.data()); - int (*sym1)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_length"); - if(sym1) - { - int len = sym1(0); - if(len > 0) - { - void (*sym2)(int,int) = (void (*)(int,int))lookupSymbol("xmms_remote_set_playlist_pos"); - if(sym2) - { - sym2(0,len - 1); - } else return false; - } else return false; - } else return false; - } else return false; - } - return true; -} - -QString KviXmmsInterface::nowPlaying() -{ - int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos"); - if(!sym)return QString(); - int pos = sym(0); - char * (*sym2)(int,int) = (char * (*)(int,int))lookupSymbol("xmms_remote_get_playlist_title"); - if(!sym2)return QString(); - return QString::fromLocal8Bit(sym2(0,pos)); -} - -QString KviXmmsInterface::mrl() -{ - int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos"); - if(!sym)return QString(); - int pos = sym(0); - char * (*sym2)(int,int) = (char * (*)(int,int))lookupSymbol("xmms_remote_get_playlist_file"); - if(!sym2)return QString(); - QString ret = QString::fromLocal8Bit(sym2(0,pos)); - if(ret.length() > 1) - if(ret[0] == '/')ret.prepend("file://"); - return ret; -} - -int KviXmmsInterface::position() -{ - int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos"); - if(!sym)return -1; - int pos = sym(0); - int (*sym2)(int,int) = (int (*)(int,int))lookupSymbol("xmms_remote_get_output_time"); - if(!sym2)return -1; - return sym2(0,pos); -} - -int KviXmmsInterface::length() -{ - int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos"); - if(!sym)return -1; - int pos = sym(0); - int (*sym2)(int,int) = (int (*)(int,int))lookupSymbol("xmms_remote_get_playlist_time"); - if(!sym2)return -1; - return sym2(0,pos); -} - -int KviXmmsInterface::getPlayListPos() -{ - int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos"); - if(!sym)return -1; - return sym(0); -} - - - -#endif //!COMPILE_ON_WINDOWS diff --git a/src/modules/mediaplayer/mp_xmmsinterface.h b/src/modules/mediaplayer/mp_xmmsinterface.h deleted file mode 100644 index df6eb04b8..000000000 --- a/src/modules/mediaplayer/mp_xmmsinterface.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef _MP_XMMSINTERFACE_H_ -#define _MP_XMMSINTERFACE_H_ -//============================================================================= -// -// File : mp_xmmsinterface.h -// Creation date : Fri 25 Mar 2005 20:04:54 by Szymon Stefanek -// -// This file is part of the KVIrc IRC client distribution -// Copyright (C) 2005-2010 Szymon Stefanek -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// Thnx to Alexander Stillich for Audacious -// media player interface hints :) -// -//============================================================================= - -#include "mp_interface.h" - -#include "kvi_settings.h" - -#include - -#if !defined(COMPILE_ON_WINDOWS) && !defined(COMPILE_ON_MINGW) - class KviXmmsInterface : public KviMediaPlayerInterface - { - public: - KviXmmsInterface(); - virtual ~KviXmmsInterface(); - protected: - QLibrary* m_pPlayerLibrary; - QString m_szPlayerLibraryName; - const char ** m_pLibraryPaths; - public: - virtual int detect(bool bStart); - virtual bool prev(); - virtual bool next(); - virtual bool play(); - virtual bool stop(); - virtual bool pause(); - virtual bool quit(); - virtual bool jumpTo(kvs_int_t &iPos); - virtual bool setVol(kvs_int_t &iVol); - virtual int getVol(); - virtual KviMediaPlayerInterface::PlayerStatus status(); - virtual QString nowPlaying(); - virtual bool playMrl(const QString &mrl); - virtual QString mrl(); - virtual int getPlayListPos(); - virtual int position(); - virtual int length(); - virtual bool getRepeat(); - virtual bool getShuffle(); - virtual bool setRepeat(bool &bVal); - virtual bool setShuffle(bool &bVal); - protected: - bool loadPlayerLibrary(); - void * lookupSymbol(const char * szSymbolName); - }; - - MP_DECLARE_DESCRIPTOR(KviXmmsInterface) - - class KviAudaciousClassicInterface : public KviXmmsInterface - { - public: - KviAudaciousClassicInterface(); - virtual ~KviAudaciousClassicInterface(); - }; - - MP_DECLARE_DESCRIPTOR(KviAudaciousClassicInterface) - -#endif //COMPILE_ON_WINDOWS - -#endif //_MP_XMMSINTERFACE_H_ diff --git a/src/modules/my/CMakeLists.txt b/src/modules/my/CMakeLists.txt index 89248553d..b1b498504 100644 --- a/src/modules/my/CMakeLists.txt +++ b/src/modules/my/CMakeLists.txt @@ -1,14 +1,14 @@ # CMakeLists for src/modules/my SET(kvimy_MOC_HDRS - idle.h + Idle.h ) SET(kvimy_SRCS libkvimy.cpp - idle_x11.cpp - idle_mac.cpp - idle.cpp + Idle_x11.cpp + Idle_mac.cpp + Idle.cpp ) # After this call, files will be moc'ed to moc_kvi_*.cpp diff --git a/src/modules/my/Idle.cpp b/src/modules/my/Idle.cpp new file mode 100644 index 000000000..4dd6f3cb1 --- /dev/null +++ b/src/modules/my/Idle.cpp @@ -0,0 +1,135 @@ +/* + * Idle.cpp - detect desktop idle time + * Copyright (C) 2003 Justin Karneges + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include"Idle.h" + +#include +#include +#include + +static IdlePlatform *platform = 0; +static int platform_ref = 0; + + +Idle::Idle() +{ + d = new Private; + d->active = false; + d->idleTime = 0; + + // try to use platform idle + if(!platform) { + IdlePlatform *p = new IdlePlatform; + if(p->init()) + platform = p; + else + delete p; + } + if(platform) + ++platform_ref; + + connect(&d->checkTimer, SIGNAL(timeout()), SLOT(doCheck())); +} + +Idle::~Idle() +{ + if(platform) { + --platform_ref; + if(platform_ref == 0) { + delete platform; + platform = 0; + } + } + delete d; +} + +bool Idle::isActive() const +{ + return d->active; +} + +bool Idle::usingPlatform() const +{ + return (platform ? true: false); +} + +void Idle::start() +{ + d->startTime = QDateTime::currentDateTime(); + + if(!platform) { + // generic idle + d->lastMousePos = QCursor::pos(); + d->idleSince = QDateTime::currentDateTime(); + } + + // poll every second (use a lower value if you need more accuracy) + d->checkTimer.start(1000); +} + +void Idle::stop() +{ + d->checkTimer.stop(); +} + +int Idle::secondsIdle() +{ + int i; + if(platform) + i = platform->secondsIdle(); + else { + QPoint curMousePos = QCursor::pos(); + QDateTime curDateTime = QDateTime::currentDateTime(); + if(d->lastMousePos != curMousePos) { + d->lastMousePos = curMousePos; + d->idleSince = curDateTime; + } + i = d->idleSince.secsTo(curDateTime); + } + + // set 'beginIdle' to the beginning of the idle time (by backtracking 'i' seconds from now) + QDateTime beginIdle = QDateTime::currentDateTime().addSecs(-i); + + // set 't' to hold the number of seconds between 'beginIdle' and 'startTime' + int t = beginIdle.secsTo(d->startTime); + + // beginIdle later than (or equal to) startTime? + if(t <= 0) { + // scoot ourselves up to the new idle start + d->startTime = beginIdle; + } + // beginIdle earlier than startTime? + else if(t > 0) { + // do nothing + } + + // how long have we been idle? + int idleTime = d->startTime.secsTo(QDateTime::currentDateTime()); + return idleTime; +} + +void Idle::doCheck() +{ + secondsIdle(secondsIdle()); +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "Idle.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/my/Idle.h b/src/modules/my/Idle.h new file mode 100644 index 000000000..1f434f1b9 --- /dev/null +++ b/src/modules/my/Idle.h @@ -0,0 +1,85 @@ +#ifndef _IDLE_H_ +#define _IDLE_H_ +/* + * Idle.h - detect desktop idle time + * Copyright (C) 2003 Justin Karneges + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + +#include "kvi_settings.h" + +#include +#include +#include +#include + +class IdlePlatform; + +class Idle : public QObject +{ + Q_OBJECT +public: + Idle(); + ~Idle(); + + bool isActive() const; + bool usingPlatform() const; + void start(); + void stop(); + int secondsIdle(); + +signals: + void secondsIdle(int); + +private slots: + void doCheck(); + +private: + class Private; + Private *d; +}; + +class IdlePlatform +{ +public: + IdlePlatform(); + ~IdlePlatform(); + + bool init() const; + int secondsIdle() const; + +private: + class Private; + Private *d; +}; + +class Idle::Private +{ +public: + Private() {} + + QPoint lastMousePos; + QDateTime idleSince; + + bool active; + int idleTime; + QDateTime startTime; + QTimer checkTimer; +}; + +#endif diff --git a/src/modules/my/Idle_mac.cpp b/src/modules/my/Idle_mac.cpp new file mode 100644 index 000000000..543b1c326 --- /dev/null +++ b/src/modules/my/Idle_mac.cpp @@ -0,0 +1,162 @@ +/* + * Idle_mac.cpp - detect desktop idle time + * Copyright (C) 2003 Tarkvara Design Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifdef COMPILE_ON_MAC + + #include "Idle.h" + #include + + // Why does Apple have to make this so complicated? + static OSStatus LoadFrameworkBundle(CFStringRef framework, CFBundleRef *bundlePtr) { + OSStatus err; + FSRef frameworksFolderRef; + CFURLRef baseURL; + CFURLRef bundleURL; + + if ( bundlePtr == nil ) return( -1 ); + + *bundlePtr = nil; + + baseURL = nil; + bundleURL = nil; + + err = FSFindFolder(kOnAppropriateDisk, kFrameworksFolderType, true, &frameworksFolderRef); + if (err == noErr) { + baseURL = CFURLCreateFromFSRef(kCFAllocatorSystemDefault, &frameworksFolderRef); + if (baseURL == nil) { + err = coreFoundationUnknownErr; + } + } + if (err == noErr) { + bundleURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault, baseURL, framework, false); + if (bundleURL == nil) { + err = coreFoundationUnknownErr; + } + } + if (err == noErr) { + *bundlePtr = CFBundleCreate(kCFAllocatorSystemDefault, bundleURL); + if (*bundlePtr == nil) { + err = coreFoundationUnknownErr; + } + } + if (err == noErr) { + if ( ! CFBundleLoadExecutable( *bundlePtr ) ) { + err = coreFoundationUnknownErr; + } + } + + // Clean up. + if (err != noErr && *bundlePtr != nil) { + CFRelease(*bundlePtr); + *bundlePtr = nil; + } + if (bundleURL != nil) { + CFRelease(bundleURL); + } + if (baseURL != nil) { + CFRelease(baseURL); + } + + return err; + } + + + class IdlePlatform::Private { + public: + EventLoopTimerRef mTimerRef; + int mSecondsIdle; + + Private() : mTimerRef(0), mSecondsIdle(0) {} + + static pascal void IdleTimerAction(EventLoopTimerRef, EventLoopIdleTimerMessage inState, void* inUserData); + + }; + + + pascal void IdlePlatform::Private::IdleTimerAction(EventLoopTimerRef, EventLoopIdleTimerMessage inState, void* inUserData) { + switch (inState) { + case kEventLoopIdleTimerStarted: + case kEventLoopIdleTimerStopped: + // Get invoked with this constant at the start of the idle period, + // or whenever user activity cancels the idle. + ((IdlePlatform::Private*)inUserData)->mSecondsIdle = 0; + break; + case kEventLoopIdleTimerIdling: + // Called every time the timer fires (i.e. every second). + ((IdlePlatform::Private*)inUserData)->mSecondsIdle++; + break; + } + } + + + IdlePlatform::IdlePlatform() { + d = new Private(); + } + + IdlePlatform::~IdlePlatform() { + RemoveEventLoopTimer(d->mTimerRef); + delete d; + } + + + // Typedef for the function we're getting back from CFBundleGetFunctionPointerForName. + typedef OSStatus (*InstallEventLoopIdleTimerPtr)(EventLoopRef inEventLoop, + EventTimerInterval inFireDelay, + EventTimerInterval inInterval, + EventLoopIdleTimerUPP inTimerProc, + void * inTimerData, + EventLoopTimerRef * outTimer); + + + bool IdlePlatform::init() { + // May already be init'ed. + if (d->mTimerRef) { + return true; + } + + // According to the docs, InstallEventLoopIdleTimer is new in 10.2. + // According to the headers, it has been around since 10.0. + // One of them is lying. We'll play it safe and weak-link the function. + + // Load the "Carbon.framework" bundle. + CFBundleRef carbonBundle; + if (LoadFrameworkBundle( CFSTR("Carbon.framework"), &carbonBundle ) != noErr) { + return false; + } + + // Load the Mach-O function pointers for the routine we will be using. + InstallEventLoopIdleTimerPtr myInstallEventLoopIdleTimer = (InstallEventLoopIdleTimerPtr)CFBundleGetFunctionPointerForName(carbonBundle, CFSTR("InstallEventLoopIdleTimer")); + if (myInstallEventLoopIdleTimer == 0) { + return false; + } + + EventLoopIdleTimerUPP timerUPP = NewEventLoopIdleTimerUPP(Private::IdleTimerAction); + if ((*myInstallEventLoopIdleTimer)(GetMainEventLoop(), kEventDurationSecond, kEventDurationSecond, timerUPP, 0, &d->mTimerRef)) { + return true; + } + + return false; + } + + + int IdlePlatform::secondsIdle() const { + return d->mSecondsIdle; + } +#endif diff --git a/src/modules/my/Idle_win.cpp b/src/modules/my/Idle_win.cpp new file mode 100644 index 000000000..3317d255d --- /dev/null +++ b/src/modules/my/Idle_win.cpp @@ -0,0 +1,109 @@ +/* + * Idle_win.cpp - detect desktop idle time + * Copyright (C) 2003 Justin Karneges + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + + #include "Idle.h" + + #include + #include< windows.h> + + typedef struct tagLASTINPUTINFO { + UINT cbSize; + DWORD dwTime; + } LASTINPUTINFO, *PLASTINPUTINFO; + + class IdlePlatform::Private + { + public: + Private() + { + GetLastInputInfo = 0; + IdleUIGetLastInputTime = 0; + lib = 0; + } + + BOOL (__stdcall * GetLastInputInfo)(PLASTINPUTINFO); + DWORD (__stdcall * IdleUIGetLastInputTime)(void); + QLibrary *lib; + }; + + IdlePlatform::IdlePlatform() + { + d = new Private; + } + + IdlePlatform::~IdlePlatform() + { + delete d->lib; + delete d; + } + + bool IdlePlatform::init() + { + if(d->lib) + return true; + void *p; + + // try to find the built-in Windows 2000 function + d->lib = new QLibrary("user32"); + if(d->lib->load() && (p = d->lib->resolve("GetLastInputInfo"))) { + d->GetLastInputInfo = (BOOL (__stdcall *)(PLASTINPUTINFO))p; + return true; + } + else { + delete d->lib; + d->lib = 0; + } + + // fall back on idleui + d->lib = new QLibrary("idleui"); + if(d->lib->load() && (p = d->lib->resolve("IdleUIGetLastInputTime"))) { + d->IdleUIGetLastInputTime = (DWORD (__stdcall *)(void))p; + return true; + } + else { + delete d->lib; + d->lib = 0; + } + + return false; + } + + int IdlePlatform::secondsIdle() + { + int i; + if(d->GetLastInputInfo) { + LASTINPUTINFO li; + li.cbSize = sizeof(LASTINPUTINFO); + bool ok = d->GetLastInputInfo(&li); + if(!ok) + return 0; + i = li.dwTime; + } + else if(d->IdleUIGetLastInputTime) { + i = d->IdleUIGetLastInputTime(); + } + else + return 0; + + return (GetTickCount() - i) / 1000; + } + +#endif diff --git a/src/modules/my/Idle_x11.cpp b/src/modules/my/Idle_x11.cpp new file mode 100644 index 000000000..9b4c4a062 --- /dev/null +++ b/src/modules/my/Idle_x11.cpp @@ -0,0 +1,96 @@ +/* + * Idle_x11.cpp - detect desktop idle time + * Copyright (C) 2003 Justin Karneges + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#ifndef COMPILE_ON_MAC +#if !defined(COMPILE_ON_WINDOWS) && !defined(COMPILE_ON_MINGW) + +#include"Idle.h" + +#ifndef COMPILE_XSS_SUPPORT + IdlePlatform::IdlePlatform() {} + IdlePlatform::~IdlePlatform() {} + bool IdlePlatform::init() const { return false; } + int IdlePlatform::secondsIdle() const { return 0; } +#else + #include + #include + #include + + #include + #include + #include + + static XErrorHandler old_handler = 0; + extern "C" int xerrhandler(Display* dpy, XErrorEvent* err) + { + if(err->error_code == BadDrawable) + return 0; + + return (*old_handler)(dpy, err); + } + + class IdlePlatform::Private + { + public: + Private() {} + + XScreenSaverInfo *ss_info; + }; + + IdlePlatform::IdlePlatform() + { + d = new Private; + d->ss_info = 0; + } + + IdlePlatform::~IdlePlatform() + { + if(d->ss_info) + XFree(d->ss_info); + if(old_handler) { + XSetErrorHandler(old_handler); + old_handler = 0; + } + delete d; + } + + bool IdlePlatform::init() const + { + if(d->ss_info) + return true; + + old_handler = XSetErrorHandler(xerrhandler); + + int event_base, error_base; + if(XScreenSaverQueryExtension(QX11Info::display(), &event_base, &error_base)) { + d->ss_info = XScreenSaverAllocInfo(); + return true; + } + return false; + } + + int IdlePlatform::secondsIdle() const + { + if(!d->ss_info) return 0; + if(!XScreenSaverQueryInfo(QX11Info::display(), QX11Info::appRootWindow(), d->ss_info)) return 0; + return d->ss_info->idle / 1000; + } +#endif +#endif +#endif diff --git a/src/modules/my/idle.cpp b/src/modules/my/idle.cpp deleted file mode 100644 index e7fd4fd5c..000000000 --- a/src/modules/my/idle.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * idle.cpp - detect desktop idle time - * Copyright (C) 2003 Justin Karneges - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include"idle.h" - -#include -#include -#include - -static IdlePlatform *platform = 0; -static int platform_ref = 0; - - -Idle::Idle() -{ - d = new Private; - d->active = false; - d->idleTime = 0; - - // try to use platform idle - if(!platform) { - IdlePlatform *p = new IdlePlatform; - if(p->init()) - platform = p; - else - delete p; - } - if(platform) - ++platform_ref; - - connect(&d->checkTimer, SIGNAL(timeout()), SLOT(doCheck())); -} - -Idle::~Idle() -{ - if(platform) { - --platform_ref; - if(platform_ref == 0) { - delete platform; - platform = 0; - } - } - delete d; -} - -bool Idle::isActive() const -{ - return d->active; -} - -bool Idle::usingPlatform() const -{ - return (platform ? true: false); -} - -void Idle::start() -{ - d->startTime = QDateTime::currentDateTime(); - - if(!platform) { - // generic idle - d->lastMousePos = QCursor::pos(); - d->idleSince = QDateTime::currentDateTime(); - } - - // poll every second (use a lower value if you need more accuracy) - d->checkTimer.start(1000); -} - -void Idle::stop() -{ - d->checkTimer.stop(); -} - -int Idle::secondsIdle() -{ - int i; - if(platform) - i = platform->secondsIdle(); - else { - QPoint curMousePos = QCursor::pos(); - QDateTime curDateTime = QDateTime::currentDateTime(); - if(d->lastMousePos != curMousePos) { - d->lastMousePos = curMousePos; - d->idleSince = curDateTime; - } - i = d->idleSince.secsTo(curDateTime); - } - - // set 'beginIdle' to the beginning of the idle time (by backtracking 'i' seconds from now) - QDateTime beginIdle = QDateTime::currentDateTime().addSecs(-i); - - // set 't' to hold the number of seconds between 'beginIdle' and 'startTime' - int t = beginIdle.secsTo(d->startTime); - - // beginIdle later than (or equal to) startTime? - if(t <= 0) { - // scoot ourselves up to the new idle start - d->startTime = beginIdle; - } - // beginIdle earlier than startTime? - else if(t > 0) { - // do nothing - } - - // how long have we been idle? - int idleTime = d->startTime.secsTo(QDateTime::currentDateTime()); - return idleTime; -} - -void Idle::doCheck() -{ - secondsIdle(secondsIdle()); -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "idle.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/my/idle.h b/src/modules/my/idle.h deleted file mode 100644 index 798f59a10..000000000 --- a/src/modules/my/idle.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef _IDLE_H_ -#define _IDLE_H_ -/* - * idle.h - detect desktop idle time - * Copyright (C) 2003 Justin Karneges - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - - -#include "kvi_settings.h" - -#include -#include -#include -#include - -class IdlePlatform; - -class Idle : public QObject -{ - Q_OBJECT -public: - Idle(); - ~Idle(); - - bool isActive() const; - bool usingPlatform() const; - void start(); - void stop(); - int secondsIdle(); - -signals: - void secondsIdle(int); - -private slots: - void doCheck(); - -private: - class Private; - Private *d; -}; - -class IdlePlatform -{ -public: - IdlePlatform(); - ~IdlePlatform(); - - bool init() const; - int secondsIdle() const; - -private: - class Private; - Private *d; -}; - -class Idle::Private -{ -public: - Private() {} - - QPoint lastMousePos; - QDateTime idleSince; - - bool active; - int idleTime; - QDateTime startTime; - QTimer checkTimer; -}; - -#endif diff --git a/src/modules/my/idle_mac.cpp b/src/modules/my/idle_mac.cpp deleted file mode 100644 index 4dc8fb480..000000000 --- a/src/modules/my/idle_mac.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - * idle_mac.cpp - detect desktop idle time - * Copyright (C) 2003 Tarkvara Design Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifdef COMPILE_ON_MAC - - #include "idle.h" - #include - - // Why does Apple have to make this so complicated? - static OSStatus LoadFrameworkBundle(CFStringRef framework, CFBundleRef *bundlePtr) { - OSStatus err; - FSRef frameworksFolderRef; - CFURLRef baseURL; - CFURLRef bundleURL; - - if ( bundlePtr == nil ) return( -1 ); - - *bundlePtr = nil; - - baseURL = nil; - bundleURL = nil; - - err = FSFindFolder(kOnAppropriateDisk, kFrameworksFolderType, true, &frameworksFolderRef); - if (err == noErr) { - baseURL = CFURLCreateFromFSRef(kCFAllocatorSystemDefault, &frameworksFolderRef); - if (baseURL == nil) { - err = coreFoundationUnknownErr; - } - } - if (err == noErr) { - bundleURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault, baseURL, framework, false); - if (bundleURL == nil) { - err = coreFoundationUnknownErr; - } - } - if (err == noErr) { - *bundlePtr = CFBundleCreate(kCFAllocatorSystemDefault, bundleURL); - if (*bundlePtr == nil) { - err = coreFoundationUnknownErr; - } - } - if (err == noErr) { - if ( ! CFBundleLoadExecutable( *bundlePtr ) ) { - err = coreFoundationUnknownErr; - } - } - - // Clean up. - if (err != noErr && *bundlePtr != nil) { - CFRelease(*bundlePtr); - *bundlePtr = nil; - } - if (bundleURL != nil) { - CFRelease(bundleURL); - } - if (baseURL != nil) { - CFRelease(baseURL); - } - - return err; - } - - - class IdlePlatform::Private { - public: - EventLoopTimerRef mTimerRef; - int mSecondsIdle; - - Private() : mTimerRef(0), mSecondsIdle(0) {} - - static pascal void IdleTimerAction(EventLoopTimerRef, EventLoopIdleTimerMessage inState, void* inUserData); - - }; - - - pascal void IdlePlatform::Private::IdleTimerAction(EventLoopTimerRef, EventLoopIdleTimerMessage inState, void* inUserData) { - switch (inState) { - case kEventLoopIdleTimerStarted: - case kEventLoopIdleTimerStopped: - // Get invoked with this constant at the start of the idle period, - // or whenever user activity cancels the idle. - ((IdlePlatform::Private*)inUserData)->mSecondsIdle = 0; - break; - case kEventLoopIdleTimerIdling: - // Called every time the timer fires (i.e. every second). - ((IdlePlatform::Private*)inUserData)->mSecondsIdle++; - break; - } - } - - - IdlePlatform::IdlePlatform() { - d = new Private(); - } - - IdlePlatform::~IdlePlatform() { - RemoveEventLoopTimer(d->mTimerRef); - delete d; - } - - - // Typedef for the function we're getting back from CFBundleGetFunctionPointerForName. - typedef OSStatus (*InstallEventLoopIdleTimerPtr)(EventLoopRef inEventLoop, - EventTimerInterval inFireDelay, - EventTimerInterval inInterval, - EventLoopIdleTimerUPP inTimerProc, - void * inTimerData, - EventLoopTimerRef * outTimer); - - - bool IdlePlatform::init() { - // May already be init'ed. - if (d->mTimerRef) { - return true; - } - - // According to the docs, InstallEventLoopIdleTimer is new in 10.2. - // According to the headers, it has been around since 10.0. - // One of them is lying. We'll play it safe and weak-link the function. - - // Load the "Carbon.framework" bundle. - CFBundleRef carbonBundle; - if (LoadFrameworkBundle( CFSTR("Carbon.framework"), &carbonBundle ) != noErr) { - return false; - } - - // Load the Mach-O function pointers for the routine we will be using. - InstallEventLoopIdleTimerPtr myInstallEventLoopIdleTimer = (InstallEventLoopIdleTimerPtr)CFBundleGetFunctionPointerForName(carbonBundle, CFSTR("InstallEventLoopIdleTimer")); - if (myInstallEventLoopIdleTimer == 0) { - return false; - } - - EventLoopIdleTimerUPP timerUPP = NewEventLoopIdleTimerUPP(Private::IdleTimerAction); - if ((*myInstallEventLoopIdleTimer)(GetMainEventLoop(), kEventDurationSecond, kEventDurationSecond, timerUPP, 0, &d->mTimerRef)) { - return true; - } - - return false; - } - - - int IdlePlatform::secondsIdle() const { - return d->mSecondsIdle; - } -#endif diff --git a/src/modules/my/idle_win.cpp b/src/modules/my/idle_win.cpp deleted file mode 100644 index 3a1469928..000000000 --- a/src/modules/my/idle_win.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * idle_win.cpp - detect desktop idle time - * Copyright (C) 2003 Justin Karneges - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ -#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - - #include "idle.h" - - #include - #include< windows.h> - - typedef struct tagLASTINPUTINFO { - UINT cbSize; - DWORD dwTime; - } LASTINPUTINFO, *PLASTINPUTINFO; - - class IdlePlatform::Private - { - public: - Private() - { - GetLastInputInfo = 0; - IdleUIGetLastInputTime = 0; - lib = 0; - } - - BOOL (__stdcall * GetLastInputInfo)(PLASTINPUTINFO); - DWORD (__stdcall * IdleUIGetLastInputTime)(void); - QLibrary *lib; - }; - - IdlePlatform::IdlePlatform() - { - d = new Private; - } - - IdlePlatform::~IdlePlatform() - { - delete d->lib; - delete d; - } - - bool IdlePlatform::init() - { - if(d->lib) - return true; - void *p; - - // try to find the built-in Windows 2000 function - d->lib = new QLibrary("user32"); - if(d->lib->load() && (p = d->lib->resolve("GetLastInputInfo"))) { - d->GetLastInputInfo = (BOOL (__stdcall *)(PLASTINPUTINFO))p; - return true; - } - else { - delete d->lib; - d->lib = 0; - } - - // fall back on idleui - d->lib = new QLibrary("idleui"); - if(d->lib->load() && (p = d->lib->resolve("IdleUIGetLastInputTime"))) { - d->IdleUIGetLastInputTime = (DWORD (__stdcall *)(void))p; - return true; - } - else { - delete d->lib; - d->lib = 0; - } - - return false; - } - - int IdlePlatform::secondsIdle() - { - int i; - if(d->GetLastInputInfo) { - LASTINPUTINFO li; - li.cbSize = sizeof(LASTINPUTINFO); - bool ok = d->GetLastInputInfo(&li); - if(!ok) - return 0; - i = li.dwTime; - } - else if(d->IdleUIGetLastInputTime) { - i = d->IdleUIGetLastInputTime(); - } - else - return 0; - - return (GetTickCount() - i) / 1000; - } - -#endif diff --git a/src/modules/my/idle_x11.cpp b/src/modules/my/idle_x11.cpp deleted file mode 100644 index 41dc87017..000000000 --- a/src/modules/my/idle_x11.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * idle_x11.cpp - detect desktop idle time - * Copyright (C) 2003 Justin Karneges - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ -#ifndef COMPILE_ON_MAC -#if !defined(COMPILE_ON_WINDOWS) && !defined(COMPILE_ON_MINGW) - -#include"idle.h" - -#ifndef COMPILE_XSS_SUPPORT - IdlePlatform::IdlePlatform() {} - IdlePlatform::~IdlePlatform() {} - bool IdlePlatform::init() const { return false; } - int IdlePlatform::secondsIdle() const { return 0; } -#else - #include - #include - #include - - #include - #include - #include - - static XErrorHandler old_handler = 0; - extern "C" int xerrhandler(Display* dpy, XErrorEvent* err) - { - if(err->error_code == BadDrawable) - return 0; - - return (*old_handler)(dpy, err); - } - - class IdlePlatform::Private - { - public: - Private() {} - - XScreenSaverInfo *ss_info; - }; - - IdlePlatform::IdlePlatform() - { - d = new Private; - d->ss_info = 0; - } - - IdlePlatform::~IdlePlatform() - { - if(d->ss_info) - XFree(d->ss_info); - if(old_handler) { - XSetErrorHandler(old_handler); - old_handler = 0; - } - delete d; - } - - bool IdlePlatform::init() const - { - if(d->ss_info) - return true; - - old_handler = XSetErrorHandler(xerrhandler); - - int event_base, error_base; - if(XScreenSaverQueryExtension(QX11Info::display(), &event_base, &error_base)) { - d->ss_info = XScreenSaverAllocInfo(); - return true; - } - return false; - } - - int IdlePlatform::secondsIdle() const - { - if(!d->ss_info) return 0; - if(!XScreenSaverQueryInfo(QX11Info::display(), QX11Info::appRootWindow(), d->ss_info)) return 0; - return d->ss_info->idle / 1000; - } -#endif -#endif -#endif diff --git a/src/modules/my/libkvimy.cpp b/src/modules/my/libkvimy.cpp index ee0e1b4d0..00972553b 100644 --- a/src/modules/my/libkvimy.cpp +++ b/src/modules/my/libkvimy.cpp @@ -32,7 +32,7 @@ #include "KviIrcConnectionServerInfo.h" #include "KviIrcServer.h" -#include "idle.h" +#include "Idle.h" Idle* g_pIdle; #define GET_KVS_CONSOLE \ diff --git a/src/modules/notifier/CMakeLists.txt b/src/modules/notifier/CMakeLists.txt index 2453bfdb1..78a1d0b5c 100644 --- a/src/modules/notifier/CMakeLists.txt +++ b/src/modules/notifier/CMakeLists.txt @@ -1,16 +1,16 @@ # CMakeLists for src/modules/notifier SET(kvinotifier_MOC_HDRS - notifierwindow.h - notifierwindowtab.h + NotifierWindow.h + NotifierWindowTab.h ) SET(kvinotifier_SRCS libkvinotifier.cpp - notifierwindow.cpp - notifiermessage.cpp - notifierwindowtab.cpp - notifierwindowborder.cpp + NotifierWindow.cpp + NotifierMessage.cpp + NotifierWindowTab.cpp + NotifierWindowBorder.cpp ) # After this call, files will be moc'ed to moc_kvi_*.cpp diff --git a/src/modules/notifier/NotifierMessage.cpp b/src/modules/notifier/NotifierMessage.cpp new file mode 100644 index 000000000..6dc7977d7 --- /dev/null +++ b/src/modules/notifier/NotifierMessage.cpp @@ -0,0 +1,99 @@ +//============================================================================= +// +// File : NotifierMessage.cpp +// Creation date : Mar 02 Nov 2004 02:41:18 by Iacopo Palazzi +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2004-2008 Iacopo +// Copyright (C) 2009 Fabio Bas < ctrlaltca at gmail dot com > +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "NotifierMessage.h" +#include "NotifierSettings.h" + +#include "KviHtmlGenerator.h" +#include "KviOptions.h" + +#include +#include + +NotifierMessage::NotifierMessage(QPixmap * pPixmap, const QString & szText) +{ + m_pLabel0 = 0; + m_pLabel1 = 0; + + m_szText=szText; + m_pPixmap=pPixmap; + + //QByteArray utf8 = szText.toUtf8(); + //if(utf8.data()) + // qDebug("NOTIFIER TEXT MESSAGE: \n%s\n",utf8.data()); + + m_pHBox = new QHBoxLayout(this); + m_pHBox->setSpacing(SPACING); + m_pHBox->setMargin(SPACING); + + updateGui(); +} + +NotifierMessage::~NotifierMessage() +{ + if(m_pLabel0) + m_pLabel0->deleteLater(); + if(m_pLabel1) + m_pLabel1->deleteLater(); + if(m_pHBox) + m_pHBox->deleteLater(); +} + +void NotifierMessage::updateGui() +{ + bool bShowImages = KVI_OPTION_BOOL(KviOption_boolIrcViewShowImages); + + if(m_pLabel0) + delete m_pLabel0; + + if(m_pLabel1) + delete m_pLabel1; + + if(bShowImages) + { + m_pLabel0 = new QLabel(this); + m_pLabel0->setFixedSize(16,16); + if(m_pPixmap) + m_pLabel0->setPixmap(*m_pPixmap); + } else { + m_pLabel0 = 0; + } + + m_pLabel1 = new QLabel(this); + m_pLabel1->setTextFormat(Qt::RichText); + m_pLabel1->setText(KviHtmlGenerator::convertToHtml(m_szText)); + m_pLabel1->setWordWrap(true); + m_pLabel1->setFont(KVI_OPTION_FONT(KviOption_fontNotifier)); + QPalette pal = m_pLabel1->palette(); + pal.setColor(QPalette::WindowText, KVI_OPTION_COLOR(KviOption_colorNotifierForeground)); + m_pLabel1->setPalette(pal); + + if(bShowImages) + { + m_pHBox->setStretch(1,99); + m_pHBox->addWidget(m_pLabel0); + } + m_pHBox->addWidget(m_pLabel1); +} diff --git a/src/modules/notifier/NotifierMessage.h b/src/modules/notifier/NotifierMessage.h new file mode 100644 index 000000000..025e5a11d --- /dev/null +++ b/src/modules/notifier/NotifierMessage.h @@ -0,0 +1,87 @@ +#ifndef _NOTIFIERMESSAGE_H_ +#define _NOTIFIERMESSAGE_H_ +//============================================================================= +// +// File : NotifierMessage.h +// Creation date : Mar 02 Nov 2004 02:41:18 by Iacopo Palazzi +// +// This file is part of the KVIrc distribution +// Copyright (C) 2004 Szymon Stefanek (pragma at kvirc dot net) +// Copyright (C) 2004-2008 Iacopo Palazzi < iakko(at)siena(dot)linux(dot)it > +// Copyright (C) 2009 Fabio Bas < ctrlaltca at gmail dot com > +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include +#include +#include +#include +#include + +/** +* \class NotifierMessage +* \brief A single message in a notifier window +* +* This is basically a single message that can appear in a notifier window +* It's made up of an icon and a rich text content +* This class is basically a QLabel with a method that translates a raw irc message to html code. +*/ +class NotifierMessage : public QWidget +{ + friend class NotifierWindow; +public: + /** + * \brief Constructs the NotifierMessage object + * \param pPixmap pointer to a message icon, can be null + * \param szText const reference to message text in irc format + * \return NotifierMessage + */ + NotifierMessage(QPixmap * pPixmap, const QString &szText); + /** + * \brief Destroys the NotifierMessage object + */ + ~NotifierMessage(); +private: + /// The message text + QString m_szText; + /// The message icon (can be null) + QPixmap * m_pPixmap; + /// Layout for the labels + QHBoxLayout * m_pHBox; + /// Label for the message icon + QLabel * m_pLabel0; + /// Label for the message text + QLabel * m_pLabel1; +public: + /** + * \brief Returns the original irc message + * \return QString + */ + inline QString text() const { return m_szText; }; + /** + * \brief Returns the message icon + * \return QPixmap * + */ + inline QPixmap * pixmap() const { return m_pPixmap; }; + /** + * \brief Updates the aspect of this message + * \return void + */ + void updateGui(); +}; + +#endif //!_NOTIFIERMESSAGE_H_ diff --git a/src/modules/notifier/NotifierSettings.h b/src/modules/notifier/NotifierSettings.h new file mode 100644 index 000000000..28e53ef3b --- /dev/null +++ b/src/modules/notifier/NotifierSettings.h @@ -0,0 +1,66 @@ +#ifndef _NOTIFIER_SETTINGS_H_ +#define _NOTIFIER_SETTINGS_H_ +//============================================================================= +// +// File : NotifierSettings.h +// Creation date : Thu 30 Dev 2004 21:21:33 by Iacopo Palazzi +// +// This file is part of the Notifier - KVIrc Distribution distribution +// Copyright (C) 2004-2008 Iacopo Palazzi < iakko(at)siena(dot)linux(dot)it > +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +// Global settings for KviNotifier + + + +#define WDG_MIN_WIDTH 370 +#define WDG_MIN_HEIGHT 160 +#define WDG_BORDER_THICKNESS 5 +#define SPACING 2 + +#define WDG_ICON_OUT 0 +#define WDG_ICON_OVER 1 +#define WDG_ICON_CLICKED 2 +#define WDG_ICON_ON 3 +#define WDG_ICON_OFF 4 + +#define NTF_TABS_FONT_BASELINE 8 + +#define MAX_MESSAGES_IN_WINDOW 20 +// keep hidden messages for 600 seconds : 10 min +#define MAX_MESSAGE_LIFETIME 600 + +#define OPACITY_STEP 0.07 + +#define NUM_OLD_COLORS 6 + +#define WDG_UPSX 1 +#define WDG_UP 2 +#define WDG_UPDX 3 +#define WDG_DWNSX 4 +#define WDG_DWN 5 +#define WDG_DWNDX 6 +#define WDG_SX 7 +#define WDG_DX 8 + +#define m_mac_bkgColor QColor(236,233,216) // Light-brown color of notifier background widget + +enum State { Hidden, Showing, Visible, Hiding, FocusingOff, FocusingOn }; +enum TabState { Normal, Highlighted, Changed }; + +#endif //_NOTIFIER_SETTINGS_H_ diff --git a/src/modules/notifier/NotifierWindow.cpp b/src/modules/notifier/NotifierWindow.cpp new file mode 100644 index 000000000..07b3f86bb --- /dev/null +++ b/src/modules/notifier/NotifierWindow.cpp @@ -0,0 +1,1153 @@ +//============================================================================= +// +// File : NotifierWindow.cpp +// Creation date : Tue Jul 6 2004 20:25:12 CEST by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2004-2008 Iacopo Palazzi < iakko(at)siena.linux.it > +// +// This program is FREE software. You can redistribute it and/or +// modify it under the linkss of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= +#include "kvi_settings.h" + +#include "NotifierMessage.h" +#include "NotifierWindow.h" +#include "NotifierWindowBorder.h" +#include "NotifierWindowTab.h" + +#include "KviIconManager.h" +#include "KviConfigurationFile.h" +#include "KviWindow.h" +#include "KviLocale.h" +#include "KviMainWindow.h" +#include "KviMircCntrl.h" +#include "KviOptions.h" +#include "KviUserInput.h" +#include "KviThemedLineEdit.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern NotifierWindow * g_pNotifierWindow; + +NotifierWindow::NotifierWindow() +: QWidget(0, +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + Qt::FramelessWindowHint | + Qt::Tool | + Qt::WindowStaysOnTopHint) +#else + Qt::FramelessWindowHint | +#ifndef COMPILE_ON_MAC + Qt::Tool | + Qt::X11BypassWindowManagerHint | +#endif + Qt::WindowStaysOnTopHint) +#endif +{ + setObjectName("kvirc_notifier_window"); + + g_pNotifierWindow = this; + + m_eState = Hidden; + m_dOpacity = 0.0; + m_pShowHideTimer = 0; + m_pBlinkTimer = 0; + m_tAutoHideAt = 0; + m_tStartedAt=0; + m_pAutoHideTimer = 0; + + m_pWndBorder = new NotifierWindowBorder(); + + setFocusPolicy(Qt::NoFocus); + setMouseTracking(true); + setAutoFillBackground(true); + + hide(); + + m_bBlinkOn = false; + + m_bCloseDown = false; + m_bPrevDown = false; + m_bNextDown = false; + m_bWriteDown = false; + + m_bLeftButtonIsPressed = false; + m_bDiagonalResizing = false; + m_bResizing = false; + + m_pContextPopup = 0; + m_pDisablePopup = 0; + + m_bDragging = false; + + m_bDisableHideOnMainWindowGotAttention = false; + + // Positioning the notifier bottom-right + QDesktopWidget * pDesktop = QApplication::desktop(); + QRect r = pDesktop->availableGeometry(pDesktop->primaryScreen()); + + m_wndRect.setRect( + r.x() + r.width() - (WDG_MIN_WIDTH + SPACING), + r.y() + r.height() - (WDG_MIN_HEIGHT + SPACING), + WDG_MIN_WIDTH, + WDG_MIN_HEIGHT); + + m_pWndTabs = new QTabWidget(this); + m_pWndTabs->setUsesScrollButtons(true); + m_pWndTabs->setTabsClosable(true); + connect(m_pWndTabs,SIGNAL(tabCloseRequested(int)),this,SLOT(slotTabCloseRequested(int))); + + m_pProgressBar = new QProgressBar(this); + m_pProgressBar->setOrientation(Qt::Vertical); + m_pProgressBar->setRange(0, 100); + m_pProgressBar->setTextVisible(false); + m_pProgressBar->setMaximumWidth(8); + m_pProgressBar->installEventFilter(this); + + m_pLineEdit = new KviThemedLineEdit(this, 0, "notifier_lineedit"); + QPalette palette=m_pLineEdit->palette(); + palette.setColor(m_pLineEdit->backgroundRole(), Qt::transparent); + m_pLineEdit->setPalette(palette); + m_pLineEdit->installEventFilter(this); + connect(m_pLineEdit,SIGNAL(returnPressed()),this,SLOT(returnPressed())); + + QGridLayout *layout = new QGridLayout; + layout->addWidget(m_pProgressBar, 0,0,2,1); + layout->addWidget(m_pWndTabs,0,1,1,1); + layout->addWidget(m_pLineEdit,1,1,1,1); + layout->setSpacing(SPACING); + + layout->setGeometry(m_pWndBorder->bodyRect()); + layout->setContentsMargins(5,25,5,5); + setLayout(layout); + + connect(g_pApp,SIGNAL(updateNotifier()),this,SLOT(updateGui())); + QTimer::singleShot(0,this,SLOT(updateGui())); +} + +NotifierWindow::~NotifierWindow() +{ + stopShowHideTimer(); + stopBlinkTimer(); + stopAutoHideTimer(); + delete m_pWndBorder; + m_pWndTabs->deleteLater(); +} + +void NotifierWindow::updateGui() +{ + setFont(KVI_OPTION_FONT(KviOption_fontNotifier)); + QPalette palette=m_pLineEdit->palette(); + palette.setColor(m_pLineEdit->foregroundRole(), KVI_OPTION_COLOR(KviOption_colorNotifierForeground)); + m_pLineEdit->setPalette(palette); + m_pLineEdit->setFont(KVI_OPTION_FONT(KviOption_fontNotifier)); + + for(int i=0; icount();++i) + { + ((NotifierWindowTab*)m_pWndTabs->widget(i))->updateGui(); + } + +} + +void NotifierWindow::addMessage(KviWindow * pWnd, const QString & szImageId, const QString & szText, unsigned int uMessageTime) +{ + QPixmap * pIcon; + QString szMessage = szText; + szMessage.replace( QRegExp("\r([^\r])*\r([^\r])+\r"), "\\2" ); + if(szImageId.isEmpty()) + pIcon = 0; + else + pIcon = g_pIconManager->getImage(szImageId); + + NotifierMessage * pMessage = new NotifierMessage(pIcon ? new QPixmap(*pIcon) : 0,szMessage); + + //search for an existing tab + NotifierWindowTab * pTab = 0, * pTmp = 0; + for(int i=0; i < m_pWndTabs->count();++i) + { + pTmp = (NotifierWindowTab*)m_pWndTabs->widget(i); + if(pTmp->wnd() == pWnd) + { + pTab = pTmp; + break; + } + } + + if(!pTab) + { + pTab = new NotifierWindowTab(pWnd, m_pWndTabs); + } + + //if the notifier is already visible, don't steal the focus from the current tab! + //the user could be writing a message on it (bug #678) + if(!isVisible()) + m_pWndTabs->setCurrentWidget(pTab); + + pTab->appendMessage(pMessage); + + if(!isActiveWindow()) + startBlinking(); + + if(uMessageTime > 0) + { + kvi_time_t tAutoHide = kvi_unixTime() + uMessageTime; + if(m_tAutoHideAt < tAutoHide) + { + m_tAutoHideAt = tAutoHide; + if(m_eState == Visible) + startAutoHideTimer(); + } + } else { + // never hide + stopAutoHideTimer(); + m_tAutoHideAt = 0; + } + + if(pWnd) + { + if(pWnd->hasAttention()) + m_bDisableHideOnMainWindowGotAttention = true; + } + + if(isVisible()) + update(); +} + +void NotifierWindow::stopShowHideTimer() +{ + if(!m_pShowHideTimer) + return; + delete m_pShowHideTimer; + m_pShowHideTimer = 0; +} + +void NotifierWindow::stopBlinkTimer() +{ + if(!m_pBlinkTimer) + return; + delete m_pBlinkTimer; + m_pBlinkTimer = 0; +} + +void NotifierWindow::stopAutoHideTimer() +{ + if(!m_pAutoHideTimer) + return; + delete m_pAutoHideTimer; + m_pAutoHideTimer = 0; + m_pProgressBar->setValue(0); +} + +// FIXME: The code for detecting fullscreen window does NOT take into account multi-screen setups. +// We also lack the code for MacOSX and Qt-only-X11 compilation. + +#if COMPILE_KDE_SUPPORT + #include + + static bool active_window_is_full_screen() + { + WId activeId = KWindowSystem::activeWindow(); + KWindowInfo wi = KWindowSystem::windowInfo(activeId, NET::WMState); + return (wi.valid() && wi.hasState(NET::FullScreen)); + } +#else // COMPILE_KDE_SUPPORT + #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + + #include + + static bool active_window_is_full_screen() + { + HWND hForeground = ::GetForegroundWindow(); + if(!hForeground) + return false; + + HWND hDesktop = ::GetDesktopWindow(); + if(hForeground == hDesktop) + return false; + + HWND hShell = ::GetShellWindow(); + if(hForeground == hShell) + return false; + + RECT rct; + ::GetWindowRect(hForeground,&rct); + + if((rct.right - rct.left) < GetSystemMetrics(SM_CXSCREEN)) + return false; + + if((rct.bottom - rct.top) < GetSystemMetrics(SM_CYSCREEN)) + return false; + + return true; + } + + #endif //COMPILE_ON_WINDOWS || COMPILE_ON_MINGW +#endif // COMPILE_KDE_SUPPORT + +void NotifierWindow::doShow(bool bDoAnimate) +{ + if(!KVI_OPTION_BOOL(KviOption_boolEnableNotifier)) + return; + + kvi_time_t tNow = kvi_unixTime(); + if(g_tNotifierDisabledUntil > tNow) + return; + g_tNotifierDisabledUntil = 0; + +#if defined(COMPILE_KDE_SUPPORT) || defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + if(KVI_OPTION_BOOL(KviOption_boolDontShowNotifierIfActiveWindowIsFullScreen)) + { + // check if the active window is full screen + if(active_window_is_full_screen()) + return; + } +#endif //COMPILE_KDE_SUPPORT || COMPILE_ON_WINDOWS || COMPILE_ON_MINGW + + switch(m_eState) + { + case Showing: + // already showing up + return; + break; + case Visible: + // already visible + return; + break; + case Hiding: + // ops.. hiding! + m_eState = Showing; + break; + case Hidden: + stopShowHideTimer(); + stopBlinkTimer(); + + m_bDragging = false; + m_bCloseDown = false; + m_bPrevDown = false; + m_bNextDown = false; + m_bWriteDown = false; + m_bBlinkOn = false; + if(bDoAnimate) + { + m_pShowHideTimer = new QTimer(); + connect(m_pShowHideTimer,SIGNAL(timeout()),this,SLOT(heartbeat())); + m_dOpacity = OPACITY_STEP; + m_eState = Showing; + m_bCrashShowWorkAround = true; + setWindowOpacity(m_dOpacity); + show(); + m_pShowHideTimer->start(40); + m_bCrashShowWorkAround = false; + } else { + m_dOpacity = 1.0; + m_eState = Visible; + show(); + startBlinking(); + startAutoHideTimer(); + } + break; + default: + break; + } +} + +bool NotifierWindow::shouldHideIfMainWindowGotAttention() +{ + if(m_bDisableHideOnMainWindowGotAttention) + return false; + NotifierWindowTab * pTab = (NotifierWindowTab *) m_pWndTabs->currentWidget(); + if(!pTab) + return false; + if(!pTab->wnd()) + return false; + return pTab->wnd()->hasAttention(); +} + +void NotifierWindow::heartbeat() +{ + bool bIncreasing; + double targetOpacity = 0; + switch(m_eState) + { + case Hidden: + hideNow(); + break; + case Visible: + stopShowHideTimer(); + m_dOpacity = 1.0; + if(!isVisible()) + show(); + else + update(); + break; + case Showing: + // if the main window got attention while + // showing up then just hide now + if(shouldHideIfMainWindowGotAttention()) + { + m_eState = Hiding; + } else { + m_dOpacity += OPACITY_STEP; + targetOpacity = isActiveWindow() ? KVI_OPTION_UINT(KviOption_uintNotifierActiveTransparency) : KVI_OPTION_UINT(KviOption_uintNotifierInactiveTransparency); + + targetOpacity/=100; + if(m_dOpacity >= targetOpacity) + { + m_dOpacity = targetOpacity; + m_eState = Visible; + stopShowHideTimer(); + startBlinking(); + startAutoHideTimer(); + } + + if(!isVisible()) + show(); + setWindowOpacity(m_dOpacity); + update(); + + } + break; + case FocusingOn: + targetOpacity = KVI_OPTION_UINT(KviOption_uintNotifierActiveTransparency); + targetOpacity /= 100; + bIncreasing = targetOpacity > m_dOpacity; + m_dOpacity += bIncreasing? + OPACITY_STEP : -(OPACITY_STEP); + if((bIncreasing && (m_dOpacity >= targetOpacity)) || + (!bIncreasing && (m_dOpacity <= targetOpacity)) + ) + { + m_dOpacity = targetOpacity; + m_eState = Visible; + stopShowHideTimer(); + } + + setWindowOpacity(m_dOpacity); + break; + case FocusingOff: + targetOpacity = KVI_OPTION_UINT(KviOption_uintNotifierInactiveTransparency); + targetOpacity /= 100; + bIncreasing = targetOpacity > m_dOpacity; + m_dOpacity += bIncreasing ? OPACITY_STEP : -(OPACITY_STEP); + //qDebug("%f %f %i %i",m_dOpacity,targetOpacity,bIncreasing,(m_dOpacity >= targetOpacity)); + if((bIncreasing && (m_dOpacity >= targetOpacity)) || + (!bIncreasing && (m_dOpacity <= targetOpacity)) + ) + { + m_dOpacity = targetOpacity; + m_eState = Visible; + stopShowHideTimer(); + } + + setWindowOpacity(m_dOpacity); + break; + case Hiding: + m_dOpacity -= OPACITY_STEP; + setWindowOpacity(m_dOpacity); + if(m_dOpacity <= 0.0) + hideNow(); + else + update(); + break; + } +} + +void NotifierWindow::hideNow() +{ + stopBlinkTimer(); + stopShowHideTimer(); + stopAutoHideTimer(); + m_eState = Hidden; + m_dOpacity = 0.0; + m_tAutoHideAt = 0; + hide(); +} + +void NotifierWindow::doHide(bool bDoAnimate) +{ + stopAutoHideTimer(); + switch(m_eState) + { + case Hiding: + // already hiding up + if(!bDoAnimate) + hideNow(); + return; + break; + case Hidden: + // already hidden + if(isVisible()) + hideNow(); + return; + break; + case Showing: + // ops.. hiding! + if(!bDoAnimate) + hideNow(); + else { + // continue animating, but hide + m_eState = Hiding; + } + break; + case Visible: + stopBlinkTimer(); + stopShowHideTimer(); + if((!bDoAnimate) || (x() != m_pWndBorder->x()) || (y() != m_pWndBorder->y())) + { + + //qDebug("just hide quickly with notifier x() %d and notifier y() % - WBorderx() %d and WBordery() %d and bDoanimate %d",x(),y(),m_pWndBorder->x(),m_pWndBorder->y(),bDoAnimate); + // the user asked to not animate or + // the window has been moved and the animation would suck anyway + // just hide quickly + hideNow(); + } else { + //qDebug("starting hide animation notifier x() %d and notifier y() % - WBorderx() %d and WBordery() %d and bDoanimate %d",x(),y(),m_pWndBorder->x(),m_pWndBorder->y(),bDoAnimate); + m_pShowHideTimer = new QTimer(); + connect(m_pShowHideTimer,SIGNAL(timeout()),this,SLOT(heartbeat())); + m_dOpacity = 1.0 - OPACITY_STEP; + m_eState = Hiding; + setWindowOpacity(m_dOpacity); + update(); + m_pShowHideTimer->start(40); + } + break; + default: + break; + } +} + +void NotifierWindow::showEvent(QShowEvent *) +{ + setGeometry(m_wndRect); +} + +void NotifierWindow::hideEvent(QHideEvent *) +{ + if(m_bCrashShowWorkAround) + return; + stopBlinkTimer(); + stopShowHideTimer(); + stopAutoHideTimer(); + m_eState = Hidden; // make sure it's true + m_tAutoHideAt = 0; // make sure it's true + m_bDisableHideOnMainWindowGotAttention = false; +} + +void NotifierWindow::startBlinking() +{ + stopBlinkTimer(); + m_bBlinkOn = false; + + if(KVI_OPTION_BOOL(KviOption_boolNotifierFlashing)) + { + m_pBlinkTimer = new QTimer(); + connect(m_pBlinkTimer,SIGNAL(timeout()),this,SLOT(blink())); + m_iBlinkCount = 0; + m_pBlinkTimer->start(1000); + } +} + +void NotifierWindow::startAutoHideTimer() +{ + stopAutoHideTimer(); + m_tStartedAt = kvi_unixTime(); + if(m_tAutoHideAt <= m_tStartedAt) + return; + + int iSecs = m_tAutoHideAt - m_tStartedAt; + if(iSecs < 5) + iSecs = 5; + m_pAutoHideTimer = new QTimer(); + + connect(m_pAutoHideTimer,SIGNAL(timeout()),this,SLOT(progressUpdate())); + m_pAutoHideTimer->start(100); +} + +void NotifierWindow::blink() +{ + m_iBlinkCount++; + m_bBlinkOn = !m_bBlinkOn; + + if(m_iBlinkCount > 100) + { + // stop blinking at a certain point and remain highlighted + m_bBlinkOn = true; + stopBlinkTimer(); + } else { + // if the main window got attention while + // showing up then just hide now + if(shouldHideIfMainWindowGotAttention()) + { + doHide(false); // don't animate: the background has almost surely changed + return; + } + } + update(); +} + +void NotifierWindow::paintEvent(QPaintEvent * e) +{ + QPainter * pPaint = new QPainter(this); + + if(m_wndRect.width() != m_pWndBorder->width() || m_wndRect.height() != m_pWndBorder->height()) + m_pWndBorder->resize(m_wndRect.size()); + + if(m_bBlinkOn) + { + m_pWndBorder->draw(pPaint,true); + } else { + m_pWndBorder->draw(pPaint); + } + + pPaint->setPen(KVI_OPTION_COLOR(KviOption_colorNotifierTitleForeground)); + pPaint->setFont(KVI_OPTION_FONT(KviOption_fontNotifierTitle)); + + QString szTitle = "KVIrc - "; + NotifierWindowTab * pTab = (NotifierWindowTab *)m_pWndTabs->currentWidget(); + if(pTab) + { + if(pTab->wnd()) + { + szTitle += pTab->wnd()->plainTextCaption(); + } else { + szTitle += "notifier"; + } + } else { + szTitle += "notifier"; + } + pPaint->drawText(m_pWndBorder->titleRect(),Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine,szTitle); + + delete pPaint; + e->ignore(); +} + +void NotifierWindow::mouseMoveEvent(QMouseEvent * e) +{ + if(!m_bLeftButtonIsPressed) + { + if(checkResizing(e->pos())) + goto sartelo; + + if(m_pWndBorder->captionRect().contains(e->pos())) + { + if(m_pWndBorder->closeRect().contains(e->pos())) + m_pWndBorder->setCloseIcon(WDG_ICON_OVER); + else + m_pWndBorder->setCloseIcon(WDG_ICON_OUT); + goto sartelo; + } + +sartelo: + update(); + } + + if(m_bDragging) + { + setCursor(Qt::SizeAllCursor); + + int iW = m_wndRect.width(); + int iH = m_wndRect.height(); + + m_wndRect.setX(m_pntPos.x() + cursor().pos().x() - m_pntDrag.x()); + m_wndRect.setY(m_pntPos.y() + cursor().pos().y() - m_pntDrag.y()); + + m_wndRect.setWidth(iW); + m_wndRect.setHeight(iH); + + setGeometry(m_wndRect); + } else if(m_bResizing) + { + resize(e->pos()); + } +} + +void NotifierWindow::mousePressEvent(QMouseEvent * e) +{ + // stop blinking first of all :) + bool bWasBlinkOn = m_bBlinkOn; + m_bBlinkOn = false; + stopBlinkTimer(); + m_tAutoHideAt = 0; + stopAutoHideTimer(); + + activateWindow(); + setFocus(); + + m_pntClick = e->pos(); + + if(e->button() == Qt::RightButton) + { + contextPopup(mapToGlobal(e->pos())); + return; + } else if(e->button() == Qt::LeftButton) + { + m_bLeftButtonIsPressed = true; + } + + if(checkResizing(m_pntClick)) + { + update(); + return; + } + + if(m_pWndBorder->captionRect().contains(e->pos())) + { + if(m_pWndBorder->closeRect().contains(e->pos())) + { + m_bCloseDown = true; + m_pWndBorder->setCloseIcon(WDG_ICON_CLICKED); + update(); + return; + } + + if(!m_bResizing) + { + m_bDragging = true; + m_pntDrag = cursor().pos(); + m_pntPos = pos(); + update(); + return; + } + } + + if(m_pWndBorder->rect().contains(e->pos()) || bWasBlinkOn) + update(); +} + +void NotifierWindow::mouseReleaseEvent(QMouseEvent * e) +{ + m_bWriteDown = false; + m_bNextDown = false; + m_bPrevDown = false; + m_bCloseDown = false; + m_bLeftButtonIsPressed = false; + m_bResizing = false; + + if(m_bDragging) + { + m_bDragging = false; + if(QApplication::overrideCursor()) + QApplication::restoreOverrideCursor(); + return; + } + + if(m_pWndBorder->captionRect().contains(e->pos())) + { + if(m_pWndBorder->closeRect().contains(e->pos())) + hideNow(); + else + update(); + } + + setCursor(-1); +} + +void NotifierWindow::keyPressEvent(QKeyEvent * e) +{ + if(e->key() == Qt::Key_Escape) + { + hideNow(); + return; + } +} + +bool NotifierWindow::checkResizing(QPoint e) +{ + if(e.y() < WDG_BORDER_THICKNESS) + { + if(e.x() < WDG_BORDER_THICKNESS) + { + //// UP LEFT CORNER //// + setCursor(Qt::SizeFDiagCursor); + if (m_bLeftButtonIsPressed) + { + m_bResizing = true; + m_whereResizing = WDG_UPSX; + } + } else if(e.x() > (size().width()-WDG_BORDER_THICKNESS)) + { + //// UP RIGHT CORNER //// + setCursor(Qt::SizeBDiagCursor); + if (m_bLeftButtonIsPressed) + { + m_bResizing = true; + m_whereResizing = WDG_UPDX; + } + } else { + //// UP SIDE //// + setCursor(Qt::SizeVerCursor); + if (m_bLeftButtonIsPressed) + { + m_bResizing = true; + m_whereResizing = WDG_UP; + } + } + } else if(e.y() > (size().height()-WDG_BORDER_THICKNESS)) + { + if(e.x() < WDG_BORDER_THICKNESS) + { + //// DOWN LEFT CORNER //// + setCursor(Qt::SizeBDiagCursor); + if(m_bLeftButtonIsPressed) + { + m_bResizing = true; + m_whereResizing = WDG_DWNSX; + } + } else if(e.x() > (size().width()-WDG_BORDER_THICKNESS)) + { + //// DOWN RIGHT CORNER //// + setCursor(Qt::SizeFDiagCursor); + if(m_bLeftButtonIsPressed) + { + m_bResizing = true; + m_whereResizing = WDG_DWNDX; + } + } else { + //// DOWN SIDE //// + setCursor(Qt::SizeVerCursor); + if(m_bLeftButtonIsPressed) + { + m_bResizing = true; + m_whereResizing = WDG_DWN; + } + } + } else { + if(e.x() < WDG_BORDER_THICKNESS) + { + //// LEFT SIZE //// + setCursor(Qt::SizeHorCursor); + if(m_bLeftButtonIsPressed) + { + m_bResizing = true; + m_whereResizing = WDG_SX; + } + } else if(e.x() > (size().width()-WDG_BORDER_THICKNESS)) + { + //// RIGHT SIZE //// + setCursor(Qt::SizeHorCursor); + if(m_bLeftButtonIsPressed) + { + m_bResizing = true; + m_whereResizing = WDG_DX; + } + } else { + //// ELSEWHERE //// + m_whereResizing = 0; + m_bResizing = false; + setCursor(-1); + } + } + return m_bResizing; +} + +void NotifierWindow::resize(QPoint, bool) +{ + if(m_whereResizing == WDG_UPSX || m_whereResizing == WDG_SX || m_whereResizing == WDG_DWNSX) + { + if((x() + width() - cursor().pos().x()) < WDG_MIN_WIDTH) + m_wndRect.setLeft(x() + width() - WDG_MIN_WIDTH); + else + m_wndRect.setLeft(cursor().pos().x()); + } + + if(m_whereResizing == WDG_UPSX || m_whereResizing == WDG_UP || m_whereResizing == WDG_UPDX) + { + if(y()+height()-cursor().pos().y() < WDG_MIN_HEIGHT) + m_wndRect.setTop(y() + height() - WDG_MIN_HEIGHT); + else + m_wndRect.setTop(cursor().pos().y()); + } + + if(m_whereResizing == WDG_DX || m_whereResizing == WDG_UPDX || m_whereResizing == WDG_DWNDX) + { + if((cursor().pos().x() - x()) > WDG_MIN_WIDTH) + m_wndRect.setRight(cursor().pos().x()); + else + m_wndRect.setRight(x() + WDG_MIN_WIDTH); + } + + if(m_whereResizing == WDG_DWN || m_whereResizing == WDG_DWNDX || m_whereResizing == WDG_DWNSX) + { + if((cursor().pos().y() - y()) > WDG_MIN_HEIGHT) + m_wndRect.setBottom(cursor().pos().y()); + else + m_wndRect.setBottom(y() + WDG_MIN_HEIGHT); + } + + showLineEdit(m_pLineEdit->isVisible()); + setGeometry(m_wndRect); +} + +inline void NotifierWindow::setCursor(int iCur) +{ + if(m_cursor.shape() != iCur) + { + if(QApplication::overrideCursor()) + QApplication::restoreOverrideCursor(); + m_cursor.setShape((Qt::CursorShape)iCur); + QApplication::setOverrideCursor(m_cursor); + } else if(iCur == -1) + { + if(QApplication::overrideCursor()) + QApplication::restoreOverrideCursor(); + } +} + +void NotifierWindow::enterEvent(QEvent *) +{ + if(!m_pShowHideTimer) + { + m_pShowHideTimer = new QTimer(); + connect(m_pShowHideTimer,SIGNAL(timeout()),this,SLOT(heartbeat())); + } + m_eState = FocusingOn; + m_pShowHideTimer->start(40); +} + +void NotifierWindow::leaveEvent(QEvent *) +{ + // Leaving the widget area, restore default cursor + m_pWndBorder->resetIcons(); + if(!m_bResizing) + setCursor(-1); + + if(!m_pShowHideTimer) + { + m_pShowHideTimer = new QTimer(); + connect(m_pShowHideTimer,SIGNAL(timeout()),this,SLOT(heartbeat())); + } + + if(m_eState!=Hidden) + { + m_eState = FocusingOff; + m_pShowHideTimer->start(40); + } +} + +void NotifierWindow::contextPopup(const QPoint & pos) +{ + if(!m_pContextPopup) + { + m_pContextPopup = new KviTalPopupMenu(this); + connect(m_pContextPopup,SIGNAL(aboutToShow()),this,SLOT(fillContextPopup())); + m_pDisablePopup = new KviTalPopupMenu(this); + } + + m_pContextPopup->popup(pos); +} + +void NotifierWindow::fillContextPopup() +{ + m_pContextPopup->clear(); + m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_EDITOR)),__tr2qs_ctx("Show/Hide input line","notifier"),this,SLOT(toggleLineEdit())); + m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CLOSE)),__tr2qs_ctx("Hide","notifier"),this,SLOT(hideNow())); + m_pContextPopup->insertSeparator(); + m_pDisablePopup->clear(); + m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),__tr2qs_ctx("1 Minute","notifier"),this,SLOT(disableFor1Minute())); + m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),__tr2qs_ctx("5 Minutes","notifier"),this,SLOT(disableFor5Minutes())); + m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),__tr2qs_ctx("15 Minutes","notifier"),this,SLOT(disableFor15Minutes())); + m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),__tr2qs_ctx("30 Minutes","notifier"),this,SLOT(disableFor30Minutes())); + m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),__tr2qs_ctx("1 Hour","notifier"),this,SLOT(disableFor60Minutes())); + m_pDisablePopup->insertSeparator(); + m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),__tr2qs_ctx("Until KVIrc is Restarted","notifier"),this,SLOT(disableUntilKVIrcRestarted())); + m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),__tr2qs_ctx("Permanently (Until Explicitly Enabled)","notifier"),this,SLOT(disablePermanently())); + + m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),__tr2qs_ctx("Disable","notifier"),m_pDisablePopup); +} + +void NotifierWindow::disableFor15Minutes() +{ + kvi_time_t tNow = kvi_unixTime(); + g_tNotifierDisabledUntil = tNow + (60 * 15); + + hideNow(); +} + +void NotifierWindow::disableFor5Minutes() +{ + kvi_time_t tNow = kvi_unixTime(); + g_tNotifierDisabledUntil = tNow + (60 * 5); + + hideNow(); +} + + +void NotifierWindow::disableFor1Minute() +{ + kvi_time_t tNow = kvi_unixTime(); + g_tNotifierDisabledUntil = tNow + 60; + + hideNow(); +} + +void NotifierWindow::disableFor30Minutes() +{ + kvi_time_t tNow = kvi_unixTime(); + g_tNotifierDisabledUntil = tNow + (60 * 30); + + hideNow(); +} + +void NotifierWindow::disableFor60Minutes() +{ + kvi_time_t tNow = kvi_unixTime(); + g_tNotifierDisabledUntil = tNow + (60 * 60); + + hideNow(); +} + +void NotifierWindow::disableUntilKVIrcRestarted() +{ + kvi_time_t tNow = kvi_unixTime(); + // in fact we just disable for one year + g_tNotifierDisabledUntil = tNow + (3600 * 24 * 360); // one year :D + // this will NOT work if the module is forcibly unloaded with /notifier.unload + // but the user should never do it :D + hideNow(); +} + +void NotifierWindow::disablePermanently() +{ + KVI_OPTION_BOOL(KviOption_boolEnableNotifier) = false; + hideNow(); +} + +void NotifierWindow::toggleLineEdit() +{ + showLineEdit(!m_pLineEdit->isVisible()); +} + +void NotifierWindow::showLineEdit(bool bShow) +{ + if(bShow) + { + if(m_pLineEdit->isVisible()) + return; + if(!((NotifierWindowTab *)m_pWndTabs->currentWidget())->wnd()) + return; + m_pLineEdit->setToolTip(""); + + QString szTip = __tr2qs_ctx("Write text or commands to window","notifier"); + szTip += " \""; + szTip += ((NotifierWindowTab *)m_pWndTabs->currentWidget())->wnd()->plainTextCaption(); + szTip += "\""; + m_pLineEdit->setToolTip(szTip); + m_pLineEdit->show(); + m_pLineEdit->setFocus(); + activateWindow(); + } else { + if(!m_pLineEdit->isVisible()) + return; + m_pLineEdit->hide(); + setFocus(); + update(); + } +} + +bool NotifierWindow::eventFilter(QObject * pEdit, QEvent * e) +{ + if(pEdit != (QObject *)m_pLineEdit) + return false; // huh ? + if(!m_pLineEdit->isVisible()) + return false; + if(e->type() == QEvent::MouseButtonPress) + { + bool bWasBlinkOn = m_bBlinkOn; + m_bBlinkOn = false; + m_tAutoHideAt = 0; + stopAutoHideTimer(); + stopBlinkTimer(); + activateWindow(); + m_pLineEdit->setFocus(); + if(bWasBlinkOn) + update(); + return true; + } + if(e->type() == QEvent::KeyPress) + { + if(((QKeyEvent *)e)->key() == Qt::Key_Escape) + { + hideNow(); + return true; + } + } + return false; +} + +void NotifierWindow::returnPressed() +{ + if(!m_pLineEdit->isVisible()) + return; + + NotifierWindowTab * pTab = (NotifierWindowTab *) m_pWndTabs->currentWidget(); + if(!pTab) + return; + if(!pTab->wnd()) + return; + + QString szTxt = m_pLineEdit->text(); + if(szTxt.isEmpty()) + return; + QString szHtml = szTxt; + szHtml.replace("<","<"); + szHtml.replace(">",">"); + KviCString szTmp(KviCString::Format,"%d",KVI_SMALLICON_OWNPRIVMSG); + + addMessage(pTab->wnd(),szTmp.ptr(),szHtml,0); + m_pLineEdit->setText(""); + KviUserInput::parse(szTxt,pTab->wnd(),QString(),1); +} + +void NotifierWindow::progressUpdate() +{ + kvi_time_t now = kvi_unixTime(); + int iProgress = (int)(100/(m_tAutoHideAt - m_tStartedAt)*(now - m_tStartedAt)); + m_pProgressBar->setValue(iProgress); + if(now >= m_tAutoHideAt) + { + m_tAutoHideAt = 0; + stopAutoHideTimer(); + doHide(true); + } +} + +void NotifierWindow::slotTabCloseRequested(int iIndex) +{ + if(m_pWndTabs) + { + NotifierWindowTab * pTab = (NotifierWindowTab *) m_pWndTabs->widget(iIndex); + m_pWndTabs->removeTab(iIndex); + if(pTab) + pTab->deleteLater(); + + if(m_pWndTabs->count()==0) + hideNow(); + } +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_NotifierWindow.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/notifier/NotifierWindow.h b/src/modules/notifier/NotifierWindow.h new file mode 100644 index 000000000..d58cde2ae --- /dev/null +++ b/src/modules/notifier/NotifierWindow.h @@ -0,0 +1,159 @@ +#ifndef _NOTIFIERWINDOW_H_ +#define _NOTIFIERWINDOW_H_ +//============================================================================= +// +// File : NotifierWindow.h +// Creation date : Tue Jul 6 2004 20:25:12 CEST by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2004 Szymon Stefanek (pragma at kvirc dot net) +// Copyright (C) 2005-2008 Iacopo Palazzi < iakko(at)siena(dot)linux(dot)it > +// +// This program is FREE software. You can redistribute it and/or +// modify it under the linkss of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "NotifierSettings.h" + +#include "kvi_settings.h" +#include "KviQString.h" +#include "KviPointerList.h" +#include "KviTalPopupMenu.h" +#include "KviTimeUtils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class QPainter; +class KviWindow; +class NotifierMessage; +class NotifierWindowBorder; +class KviNotifierWindowTabs; +class KviThemedLineEdit; + +extern kvi_time_t g_tNotifierDisabledUntil; + +class NotifierWindow : public QWidget +{ + Q_OBJECT +public: + NotifierWindow(); + ~NotifierWindow(); +protected: + QTimer * m_pShowHideTimer; + QTimer * m_pBlinkTimer; + QTimer * m_pAutoHideTimer; + State m_eState; + bool m_bBlinkOn; + double m_dOpacity; + + bool m_bCloseDown; + bool m_bPrevDown; + bool m_bNextDown; + bool m_bWriteDown; + bool m_bCrashShowWorkAround; + + QRect m_wndRect; + + NotifierMessage * m_pCurrentMessage; + KviThemedLineEdit * m_pLineEdit; + + bool m_bDragging; + bool m_bLeftButtonIsPressed; + bool m_bDiagonalResizing; + bool m_bResizing; + + int m_whereResizing; + + QPoint m_pntDrag; + QPoint m_pntPos; + QPoint m_pntClick; + int m_iBlinkCount; + KviTalPopupMenu * m_pContextPopup; + KviTalPopupMenu * m_pDisablePopup; + KviWindow * m_pWindowToRaise; + kvi_time_t m_tAutoHideAt; + kvi_time_t m_tStartedAt; + QTime m_qtStartedAt; + bool m_bDisableHideOnMainWindowGotAttention; + + QCursor m_cursor; + + QTabWidget * m_pWndTabs; + QProgressBar * m_pProgressBar; + NotifierWindowBorder * m_pWndBorder; +public: + void doShow(bool bDoAnimate); + void doHide(bool bDoAnimate); + int textWidth(); + void addMessage(KviWindow * pWnd,const QString &szImageId,const QString &szText,unsigned int uMessageTime); + void setDisableHideOnMainWindowGotAttention(bool b){ m_bDisableHideOnMainWindowGotAttention = b; }; + void showLineEdit(bool bShow); + inline int countTabs() const { if(m_pWndTabs)return m_pWndTabs->count(); return 0; }; + inline State state() const { return m_eState; }; +protected: + virtual void showEvent(QShowEvent *e); + virtual void hideEvent(QHideEvent * e); + virtual void paintEvent(QPaintEvent * e); + virtual void mousePressEvent(QMouseEvent * e); + virtual void mouseReleaseEvent(QMouseEvent * e); + virtual void mouseMoveEvent(QMouseEvent * e); + virtual void leaveEvent(QEvent * e); + virtual void enterEvent(QEvent * e); + virtual bool eventFilter(QObject * pEdit,QEvent * e); + virtual void keyPressEvent ( QKeyEvent * e ); +public slots: + void hideNow(); + void toggleLineEdit(); + void slotTabCloseRequested(int index); +protected slots: + void blink(); + void heartbeat(); + void returnPressed(); + void updateGui(); + void fillContextPopup(); + void disableFor1Minute(); + void disableFor5Minutes(); + void disableFor15Minutes(); + void disableFor30Minutes(); + void disableFor60Minutes(); + void disableUntilKVIrcRestarted(); + void disablePermanently(); + void progressUpdate(); +private: + void contextPopup(const QPoint &pos); + void startBlinking(); +// void computeRect(); + void stopShowHideTimer(); + void stopBlinkTimer(); + void stopAutoHideTimer(); + void startAutoHideTimer(); + bool shouldHideIfMainWindowGotAttention(); + void setCursor(int); + void resize(QPoint p, bool = true); + void redrawText(); + bool checkResizing(QPoint); +}; + +#endif //_NOTIFIERWINDOW_H_ diff --git a/src/modules/notifier/NotifierWindowBorder.cpp b/src/modules/notifier/NotifierWindowBorder.cpp new file mode 100644 index 000000000..a47d3a64c --- /dev/null +++ b/src/modules/notifier/NotifierWindowBorder.cpp @@ -0,0 +1,205 @@ +//============================================================================= +// +// File : NotifierWindowBorder.cpp +// Creation date : Mon 03 Jan 2005 02:27:22 by Iacopo Palazzi +// +// This file is part of the KVIrc distribution +// Copyright (C) 2005-2008 Iacopo Palazzi < iakko(at)siena(dot)linux(dot)it > +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "NotifierWindowBorder.h" +#include "NotifierWindowTab.h" + +#include "KviIconManager.h" + +#include + +NotifierWindowBorder::NotifierWindowBorder(QSize s) +{ + loadImages(); + resize(s); +} + +NotifierWindowBorder::~NotifierWindowBorder() +{ +} + +void NotifierWindowBorder::loadImages() +{ + // Normal Border + + QPixmap * p; + + if((p = g_pIconManager->getPixmap("notifier_pix_wnd_sx.png"))) + m_pixSX_N = *p; + if((p = g_pIconManager->getPixmap("notifier_pix_wnd_dx.png"))) + m_pixDX_N = *p; + if((p = g_pIconManager->getPixmap("notifier_pix_wnd_dwn.png"))) + m_pixDWN_N = *p; + if((p = g_pIconManager->getPixmap("notifier_pix_wnd_dwndx.png"))) + m_pixDWNDX_N = *p; + if((p = g_pIconManager->getPixmap("notifier_pix_wnd_dwnsx.png"))) + m_pixDWNSX_N = *p; + if((p = g_pIconManager->getPixmap("notifier_pix_caption_sx.png"))) + m_pixCaptionSX_N = *p; + if((p = g_pIconManager->getPixmap("notifier_pix_caption_dx.png"))) + m_pixCaptionDX_N = *p; + if((p = g_pIconManager->getPixmap("notifier_pix_caption_bkg.png"))) + m_pixCaptionBKG_N = *p; + + if((p = g_pIconManager->getPixmap("notifier_icon_close_out.png"))) + m_pixIconClose_out_N = *p; + if((p = g_pIconManager->getPixmap("notifier_icon_close_over.png"))) + m_pixIconClose_over_N = *p; + if((p = g_pIconManager->getPixmap("notifier_icon_close_clicked.png"))) + m_pixIconClose_clicked_N = *p; + + // Highlighted Border + + if((p = g_pIconManager->getPixmap("notifier_pix_wnd_sx_hl.png"))) + m_pixSX_HL = *p; + if((p = g_pIconManager->getPixmap("notifier_pix_wnd_dx_hl.png"))) + m_pixDX_HL = *p; + if((p = g_pIconManager->getPixmap("notifier_pix_wnd_dwn_hl.png"))) + m_pixDWN_HL = *p; + if((p = g_pIconManager->getPixmap("notifier_pix_wnd_dwndx_hl.png"))) + m_pixDWNDX_HL = *p; + if((p = g_pIconManager->getPixmap("notifier_pix_wnd_dwnsx_hl.png"))) + m_pixDWNSX_HL = *p; + if((p = g_pIconManager->getPixmap("notifier_pix_caption_sx_hl.png"))) + m_pixCaptionSX_HL = *p; + if((p = g_pIconManager->getPixmap("notifier_pix_caption_dx_hl.png"))) + m_pixCaptionDX_HL = *p; + if((p = g_pIconManager->getPixmap("notifier_pix_caption_bkg_hl.png"))) + m_pixCaptionBKG_HL = *p; + + if((p = g_pIconManager->getPixmap("notifier_icon_close_out_hl.png"))) + m_pixIconClose_out_HL = *p; + if((p = g_pIconManager->getPixmap("notifier_icon_close_over_hl.png"))) + m_pixIconClose_over_HL = *p; + if((p = g_pIconManager->getPixmap("notifier_icon_close_clicked_hl.png"))) + m_pixIconClose_clicked_HL = *p; + + setPics(); + setCloseIcon(WDG_ICON_OUT); + + if ( m_pixCaptionDX->height()==m_pixCaptionSX->height() && m_pixCaptionDX->height()==m_pixCaptionBKG->height()) // just to be sure that the height is fitting + m_captionRect.setHeight(m_pixCaptionDX->height()); + +} + +void NotifierWindowBorder::setPics(bool b) +{ + if (b) { + m_pixSX = &m_pixSX_HL; + m_pixDX = &m_pixDX_HL; + m_pixDWN = &m_pixDWN_HL; + m_pixDWNSX = &m_pixDWNSX_HL; + m_pixDWNDX = &m_pixDWNDX_HL; + m_pixCaptionSX = &m_pixCaptionSX_HL; + m_pixCaptionDX = &m_pixCaptionDX_HL; + m_pixCaptionBKG = &m_pixCaptionBKG_HL; + m_pixIconClose_out = &m_pixIconClose_out_HL; + m_pixIconClose_over = &m_pixIconClose_over_HL; + m_pixIconClose_clicked = &m_pixIconClose_clicked_HL; + } else { + m_pixSX = &m_pixSX_N; + m_pixDX = &m_pixDX_N; + m_pixDWN = &m_pixDWN_N; + m_pixDWNSX = &m_pixDWNSX_N; + m_pixDWNDX = &m_pixDWNDX_N; + m_pixCaptionSX = &m_pixCaptionSX_N; + m_pixCaptionDX = &m_pixCaptionDX_N; + m_pixCaptionBKG = &m_pixCaptionBKG_N; + m_pixIconClose_out = &m_pixIconClose_out_N; + m_pixIconClose_over = &m_pixIconClose_over_N; + m_pixIconClose_clicked = &m_pixIconClose_clicked_N; + } +} + +void NotifierWindowBorder::setWidth(int w) +{ + m_iRctWidth = w; + recalculatePositions(); +} + +void NotifierWindowBorder::setHeight(int h) +{ + m_iRctHeight = h; + recalculatePositions(); +} + +void NotifierWindowBorder::recalculatePositions() +{ + m_rct.setHeight(m_iRctHeight); + m_rct.setWidth(m_iRctWidth); + m_rct.setTopLeft(QPoint(0,0)); + + m_closeIconRect.setX(m_rct.width()-m_pixCaptionDX->width()-m_pixIconClose->width()); + m_closeIconRect.setY(2); + m_closeIconRect.setWidth(m_pixIconClose->width()); + m_closeIconRect.setHeight(m_pixIconClose->height()); + + m_captionRect.setTopLeft( m_rct.topLeft() ); + m_captionRect.setSize( QSize(m_rct.width(),m_pixCaptionDX->height()) ); + + m_bodyRect.setTopLeft( QPoint(m_pixCaptionDX->width(),m_captionRect.height()) ); + m_bodyRect.setSize( QSize(m_captionRect.width()-(2*m_pixCaptionDX->width()),m_rct.height()-m_captionRect.height()-m_pixDWN->height()) ); + + m_titleRect.setTopLeft( QPoint(m_pixCaptionSX->width(),0) ); + m_titleRect.setSize( QSize(m_rct.width()-m_pixCaptionSX->width()-m_pixCaptionDX->width()-m_pixIconClose->width(),m_captionRect.height())); + +} + +void NotifierWindowBorder::setCloseIcon(int state) +{ + m_eIconState = state; + switch (m_eIconState) { + case WDG_ICON_OUT: m_pixIconClose = m_pixIconClose_out; break; + case WDG_ICON_OVER: m_pixIconClose = m_pixIconClose_over; break; + case WDG_ICON_CLICKED: m_pixIconClose = m_pixIconClose_clicked; break; + }; +} + +void NotifierWindowBorder::resetIcons() +{ + setCloseIcon(WDG_ICON_OUT); +} + +void NotifierWindowBorder::draw(QPainter * p, bool b) +{ + setPics(b); + setCloseIcon(m_eIconState); + + // Draw the caption + p->drawPixmap(m_captionRect.x(), m_captionRect.y(), *m_pixCaptionSX); + p->drawTiledPixmap(m_pixCaptionSX->width(), 0, m_captionRect.width() - (m_pixCaptionSX->width() + m_pixCaptionDX->width()), m_captionRect.height(), *m_pixCaptionBKG); + p->drawPixmap(m_captionRect.width() - m_pixCaptionDX->width(), 0, *m_pixCaptionDX); + + // Draw the tiled borders + p->drawTiledPixmap(0, m_captionRect.height(), m_pixSX->width(), m_bodyRect.height(), *m_pixSX); + p->drawTiledPixmap(m_bodyRect.width() + m_bodyRect.x(), m_captionRect.height(), m_pixDX->width(), m_bodyRect.height(), *m_pixDX); + p->drawTiledPixmap(m_pixDWNSX->width(), m_captionRect.height() + m_bodyRect.height(), m_bodyRect.width() + 1, m_pixDWN->height(), *m_pixDWN); + + // Draw down corners + p->drawPixmap(0, m_captionRect.height() + m_bodyRect.height(), *m_pixDWNSX); + p->drawPixmap(m_bodyRect.width() + m_bodyRect.x(), m_captionRect.height() + m_bodyRect.height(), *m_pixDWNDX); + + //Drawing icons + p->drawPixmap(m_closeIconRect.x(), m_closeIconRect.y(), *m_pixIconClose); +} diff --git a/src/modules/notifier/NotifierWindowBorder.h b/src/modules/notifier/NotifierWindowBorder.h new file mode 100644 index 000000000..b59d90b74 --- /dev/null +++ b/src/modules/notifier/NotifierWindowBorder.h @@ -0,0 +1,130 @@ +#ifndef _KVINOTIFIERWINDOWBORDER_H_ +#define _KVINOTIFIERWINDOWBORDER_H_ +//============================================================================= +// +// File : NotifierWindowBorder.h +// Creation date : Mon 03 Jan 2005 02:27:22 by Iacopo Palazzi +// +// This file is part of the KVIrc distribution +// Copyright (C) 2005-2008 Iacopo Palazzi < iakko(at)siena(dot)linux(dot)it > +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "NotifierSettings.h" + +#include +#include +#include + +class QPainter; + +class NotifierWindowBorder +{ +public: + NotifierWindowBorder(QSize = QSize(WDG_MIN_WIDTH,WDG_MIN_HEIGHT)); + ~NotifierWindowBorder(); + +// ================================ +// Put members declaration below... +// ================================ +private: + QRect m_rct; + QPoint m_pnt; + + QRect m_closeIconRect; + + QRect m_captionRect; + QRect m_bodyRect; + QRect m_titleRect; + + // Pictures + QPixmap * m_pixSX; + QPixmap * m_pixDX; + QPixmap * m_pixDWN; + QPixmap * m_pixDWNSX; + QPixmap * m_pixDWNDX; + QPixmap * m_pixCaptionSX; + QPixmap * m_pixCaptionDX; + QPixmap * m_pixCaptionBKG; + QPixmap * m_pixIconClose_out; + QPixmap * m_pixIconClose_over; + QPixmap * m_pixIconClose_clicked; + QPixmap * m_pixIconClose; + + QPixmap m_pixSX_N; + QPixmap m_pixDX_N; + QPixmap m_pixDWN_N; + QPixmap m_pixDWNSX_N; + QPixmap m_pixDWNDX_N; + QPixmap m_pixCaptionSX_N; + QPixmap m_pixCaptionDX_N; + QPixmap m_pixCaptionBKG_N; + QPixmap m_pixIconClose_out_N; + QPixmap m_pixIconClose_over_N; + QPixmap m_pixIconClose_clicked_N; + + QPixmap m_pixSX_HL; + QPixmap m_pixDX_HL; + QPixmap m_pixDWN_HL; + QPixmap m_pixDWNSX_HL; + QPixmap m_pixDWNDX_HL; + QPixmap m_pixCaptionSX_HL; + QPixmap m_pixCaptionDX_HL; + QPixmap m_pixCaptionBKG_HL; + QPixmap m_pixIconClose_out_HL; + QPixmap m_pixIconClose_over_HL; + QPixmap m_pixIconClose_clicked_HL; + + int m_eIconState; + int m_iRctWidth; + int m_iRctHeight; +private: + void loadImages(); + void recalculatePositions(); + +public: + // reading methods... + void setWidth(int w); + void setHeight(int h); + void resize(int w, int h) { setWidth(w); setHeight(h); }; + void resize(QSize r) { setWidth(r.width()); setHeight(r.height()); }; + void setGeometry(QRect r) { r.topLeft(); r.size(); /*qDebug("x,y: %d,%d", r.x(), r.y()); qDebug("w,h: %d,%d", r.width(), r.height());*/ }; + void setGeometry(QPoint p, QSize s) { setPoint (p.x(), p.y()); setWidth (s.width()); setHeight (s.height()); }; + + void setPoint(int x, int y) { m_pnt.setX(x); m_pnt.setY(y); m_rct.setX(x); m_rct.setY(y); }; + + void setCloseIcon(int state); + void resetIcons(); + + // writing methods... + inline int x() const { return m_pnt.x(); }; + inline int y() const { return m_pnt.y(); }; + inline int width() const { return m_rct.width(); }; + inline int height() const { return m_rct.height(); }; + inline int baseLine() const { return (y()+height()); }; + + inline QRect bodyRect() const { return m_bodyRect; }; + inline QRect captionRect() const { return m_captionRect; }; + inline QRect rect() const { return m_rct; }; + inline QRect closeRect() const { return m_closeIconRect; }; + inline QRect titleRect() const { return m_titleRect; }; + + void draw(QPainter *, bool b = false); + void setPics(bool b = false); +}; + +#endif //!_KVINOTIFIERWINDOWBORDER_H_ diff --git a/src/modules/notifier/NotifierWindowTab.cpp b/src/modules/notifier/NotifierWindowTab.cpp new file mode 100644 index 000000000..dc47a3535 --- /dev/null +++ b/src/modules/notifier/NotifierWindowTab.cpp @@ -0,0 +1,230 @@ +//============================================================================= +// +// File : NotifierWindowTab.cpp +// File : NotifierWindowTab.h +// Creation date : Tue 07 Jul 2009 10:28 by Fabio Bas +// +// This file is part of the KVIrc distribution +// Copyright (C) 2009 Fabio Bas < ctrlaltca at gmail dot com > +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "NotifierMessage.h" +#include "NotifierWindowTab.h" +#include "NotifierWindow.h" +#include "NotifierSettings.h" + +#include "KviApplication.h" +#include "KviConfigurationFile.h" +#include "KviLocale.h" +#include "KviMainWindow.h" +#include "KviOptions.h" +#include "KviPixmapUtils.h" +#include "KviWindow.h" + +#include +#include +#include +#include +#include +#include + +#ifdef COMPILE_PSEUDO_TRANSPARENCY + #include + extern KVIRC_API QPixmap * g_pShadedChildGlobalDesktopBackground; +#endif + +extern NotifierWindow * g_pNotifierWindow; + +NotifierWindowTab::NotifierWindowTab(KviWindow * pWnd, QTabWidget * pParent) +: QScrollArea(pParent) +{ + m_pWnd = pWnd; + if(m_pWnd) + { + m_szLabel = m_pWnd->windowName(); + connect(pWnd,SIGNAL(windowNameChanged()),this,SLOT(labelChanged())); + connect(pWnd,SIGNAL(destroyed()),this,SLOT(closeMe())); + } else { + m_szLabel = "----"; + } + + if(pParent) + { + m_pParent = pParent; + m_pParent->addTab(this, m_szLabel); + } + + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + + if(verticalScrollBar()) + connect(verticalScrollBar(),SIGNAL(rangeChanged(int, int)),this, SLOT(scrollRangeChanged(int, int))); + + QPalette pal = palette(); + pal.setColor(backgroundRole(), Qt::transparent); + setPalette(pal); + + m_pVWidget = new QWidget(viewport()); + m_pVBox = new QVBoxLayout(m_pVWidget); + m_pVBox->setSizeConstraint(QLayout::SetFixedSize); + m_pVBox->setSpacing(SPACING); + m_pVBox->setMargin(SPACING); + + setWidget(m_pVWidget); +} + +NotifierWindowTab::~NotifierWindowTab() +{ + if(m_pVBox) + m_pVBox->deleteLater(); + if(m_pVWidget) + m_pVWidget->deleteLater(); +} + +void NotifierWindowTab::appendMessage(NotifierMessage * pMessage) +{ + m_pVBox->addWidget(pMessage); + pMessage->setFixedWidth(viewport()->width()); + + while(m_pVBox->count() > MAX_MESSAGES_IN_WINDOW) + { + QLayoutItem * pTmp = m_pVBox->takeAt(0); + NotifierMessage * pTmp2 = (NotifierMessage*)pTmp->widget(); + if(pTmp2) + pTmp2->deleteLater(); + } +} + +void NotifierWindowTab::updateGui() +{ + for(int i=0; icount(); ++i) + { + QLayoutItem * pTmp = m_pVBox->itemAt(i); + NotifierMessage * pTmp2 = (NotifierMessage*)pTmp->widget(); + if(pTmp2) + pTmp2->updateGui(); + } +} + +void NotifierWindowTab::scrollRangeChanged(int, int) +{ + //this is the autoscroll + if(verticalScrollBar()) + verticalScrollBar()->triggerAction(QAbstractSlider::SliderToMaximum); +} + +void NotifierWindowTab::labelChanged() +{ + if(!m_pWnd || !m_pParent) + return; + + int iIdx = m_pParent->indexOf(this); + m_szLabel = m_pWnd->windowName(); + if(iIdx > -1) + m_pParent->setTabText(iIdx, m_szLabel); +} + +void NotifierWindowTab::mouseDoubleClickEvent(QMouseEvent *) +{ + if(!m_pWnd || !g_pNotifierWindow) + return; + if(!g_pApp->windowExists(m_pWnd)) + return; + + g_pNotifierWindow->hideNow(); + + if(m_pWnd->mdiParent()) + { + m_pWnd->frame()->raise(); + m_pWnd->frame()->setFocus(); + m_pWnd->frame()->setWindowState((m_pWnd->frame()->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); + if(!m_pWnd->frame()->isVisible()) + m_pWnd->frame()->show(); + } + + m_pWnd->frame()->setActiveWindow(m_pWnd); +} + +void NotifierWindowTab::closeMe() +{ + //our window has been closed + if(m_pParent && g_pNotifierWindow) + { + int iIdx = m_pParent->indexOf(this); + if(iIdx != -1) + { + g_pNotifierWindow->slotTabCloseRequested(iIdx); + } + } +} + +void NotifierWindowTab::resizeEvent(QResizeEvent *) +{ + if(m_pVBox) + { + int iWidth = viewport()->width(); + NotifierMessage * pMessage; + for(int i=0; i < m_pVBox->count(); i++) + { + pMessage = (NotifierMessage *)m_pVBox->itemAt(i)->widget(); + if(pMessage) + pMessage->setFixedWidth(iWidth); + } + } +} + +void NotifierWindowTab::paintEvent(QPaintEvent * e) +{ + QPainter * pPainter = new QPainter(viewport()); + + //make sure you clean your widget with a transparent + // color before doing any rendering + // note the usage of a composition mode Source + // it's important! + + #ifdef COMPILE_PSEUDO_TRANSPARENCY + if(KVI_OPTION_BOOL(KviOption_boolUseCompositingForTransparency) && g_pApp->supportsCompositing()) + { + pPainter->save(); + pPainter->setCompositionMode(QPainter::CompositionMode_Source); + QColor col = KVI_OPTION_COLOR(KviOption_colorGlobalTransparencyFade); + col.setAlphaF((float)((float)KVI_OPTION_UINT(KviOption_uintGlobalTransparencyChildFadeFactor) / (float)100)); + pPainter->fillRect(e->rect(), col); + pPainter->restore(); + } else if(g_pShadedChildGlobalDesktopBackground) + { + QPoint pnt = mapToGlobal(e->rect().topLeft()); + pPainter->drawTiledPixmap(e->rect(),*(g_pShadedChildGlobalDesktopBackground), pnt); + } else { + #endif + QPixmap * pPix = KVI_OPTION_PIXMAP(KviOption_pixmapNotifierBackground).pixmap(); + + if(pPix) + KviPixmapUtils::drawPixmapWithPainter(pPainter,pPix,KVI_OPTION_UINT(KviOption_uintNotifierPixmapAlign),e->rect(),e->rect().width(),e->rect().height()); + else pPainter->fillRect(e->rect(),KVI_OPTION_COLOR(KviOption_colorNotifierBackground)); + #ifdef COMPILE_PSEUDO_TRANSPARENCY + } + #endif + + delete pPainter; + e->ignore(); +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_NotifierWindowTab.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/notifier/NotifierWindowTab.h b/src/modules/notifier/NotifierWindowTab.h new file mode 100644 index 000000000..5a07f387d --- /dev/null +++ b/src/modules/notifier/NotifierWindowTab.h @@ -0,0 +1,120 @@ +#ifndef _KVINOTIFIERWINDOWTAB_H_ +#define _KVINOTIFIERWINDOWTAB_H_ +//============================================================================= +// +// File : NotifierWindowTab.h +// Creation date : Tue 07 Jul 2009 10:28 by Fabio Bas +// +// This file is part of the KVIrc distribution +// Copyright (C) 2009 Fabio Bas < ctrlaltca at gmail dot com > +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +/** +* \file NotifierWindowTab.h +* \author Fabio Bas +* \brief Defines the tab page for the notifier object +*/ + +#include "NotifierMessage.h" + +#include "kvi_settings.h" + +#include + +class QVBoxLayout; +class QWidget; +class QTabWidget; +class QPainter; +class KviWindow; + +/** +* \class NotifierWindowTab +* \brief Defines an object for every single tab about the tabs area +*/ +class NotifierWindowTab : public QScrollArea +{ + Q_OBJECT +public: + /** + * \brief Creates the tab object + * \param pWnd The name of the window represented by the tab + * \param pParent The parent area container + * \return NotifierWindowTab + */ + NotifierWindowTab(KviWindow * pWnd, QTabWidget * pParent); + + /** + * \brief Destroys the tab object + */ + ~NotifierWindowTab(); +private: + QString m_szLabel; + KviWindow * m_pWnd; + QTabWidget * m_pParent; + QVBoxLayout * m_pVBox; + QWidget * m_pVWidget; +public: + /** + * \brief Appends the given message to the window + * \param pMessage The message received to append + * \return void + */ + void appendMessage(NotifierMessage * pMessage); + + /** + * \brief Updates the GUI + * \return void + */ + void updateGui(); + + /** + * \brief Returns the name of the current window + * \return QString + */ + inline QString label() const { return m_szLabel; }; + + /** + * \brief Returns the pointer of the current window + * \return KviWindow * + */ + inline KviWindow * wnd() const { return m_pWnd; }; +protected: + virtual void mouseDoubleClickEvent(QMouseEvent * e); + virtual void resizeEvent(QResizeEvent * e); + virtual void paintEvent(QPaintEvent * e); +private slots: + /** + * \brief Emitted when the scrollbar range is changed + * \return void + */ + void scrollRangeChanged(int, int); + + /** + * \brief Emitted when the window changes its name + * \return void + */ + void labelChanged(); + + /** + * \brief Emitted when the window is being destroyed + * \return void + */ + void closeMe(); +}; + +#endif //!_KVINOTIFIERWINDOWTAB_H_ diff --git a/src/modules/notifier/libkvinotifier.cpp b/src/modules/notifier/libkvinotifier.cpp index 0b71a6450..1943faffc 100644 --- a/src/modules/notifier/libkvinotifier.cpp +++ b/src/modules/notifier/libkvinotifier.cpp @@ -23,8 +23,8 @@ // //============================================================================= -#include "notifierwindow.h" -#include "notifiermessage.h" +#include "NotifierWindow.h" +#include "NotifierMessage.h" #include "KviModule.h" #include "KviKvsVariant.h" @@ -38,7 +38,7 @@ #include -KviNotifierWindow * g_pNotifierWindow = 0; +NotifierWindow * g_pNotifierWindow = 0; kvi_time_t g_tNotifierDisabledUntil = 0; /* @@ -119,7 +119,7 @@ static bool notifier_kvs_cmd_message(KviKvsModuleCommandCall * c) KVSM_PARAMETERS_END(c) if(!g_pNotifierWindow) - g_pNotifierWindow = new KviNotifierWindow(); + g_pNotifierWindow = new NotifierWindow(); QString szIco=""; QString szWnd=""; @@ -293,7 +293,7 @@ static bool notifier_module_ctrl(KviModule *, const char * pcOperation, void * p return false; if(!g_pNotifierWindow) - g_pNotifierWindow = new KviNotifierWindow(); + g_pNotifierWindow = new NotifierWindow(); g_pNotifierWindow->addMessage(p->pWindow,p->szIcon,p->szMessage,p->uMessageLifetime); g_pNotifierWindow->doShow(KVI_OPTION_BOOL(KviOption_boolNotifierFading) ? true : false); diff --git a/src/modules/notifier/notifiermessage.cpp b/src/modules/notifier/notifiermessage.cpp deleted file mode 100644 index 67c43a244..000000000 --- a/src/modules/notifier/notifiermessage.cpp +++ /dev/null @@ -1,99 +0,0 @@ -//============================================================================= -// -// File : notifiermessage.cpp -// Creation date : Mar 02 Nov 2004 02:41:18 by Iacopo Palazzi -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2004-2008 Iacopo -// Copyright (C) 2009 Fabio Bas < ctrlaltca at gmail dot com > -// -// This program is FREE software. You can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "notifiermessage.h" -#include "notifiersettings.h" - -#include "KviHtmlGenerator.h" -#include "KviOptions.h" - -#include -#include - -KviNotifierMessage::KviNotifierMessage(QPixmap * pPixmap, const QString & szText) -{ - m_pLabel0 = 0; - m_pLabel1 = 0; - - m_szText=szText; - m_pPixmap=pPixmap; - - //QByteArray utf8 = szText.toUtf8(); - //if(utf8.data()) - // qDebug("NOTIFIER TEXT MESSAGE: \n%s\n",utf8.data()); - - m_pHBox = new QHBoxLayout(this); - m_pHBox->setSpacing(SPACING); - m_pHBox->setMargin(SPACING); - - updateGui(); -} - -KviNotifierMessage::~KviNotifierMessage() -{ - if(m_pLabel0) - m_pLabel0->deleteLater(); - if(m_pLabel1) - m_pLabel1->deleteLater(); - if(m_pHBox) - m_pHBox->deleteLater(); -} - -void KviNotifierMessage::updateGui() -{ - bool bShowImages = KVI_OPTION_BOOL(KviOption_boolIrcViewShowImages); - - if(m_pLabel0) - delete m_pLabel0; - - if(m_pLabel1) - delete m_pLabel1; - - if(bShowImages) - { - m_pLabel0 = new QLabel(this); - m_pLabel0->setFixedSize(16,16); - if(m_pPixmap) - m_pLabel0->setPixmap(*m_pPixmap); - } else { - m_pLabel0 = 0; - } - - m_pLabel1 = new QLabel(this); - m_pLabel1->setTextFormat(Qt::RichText); - m_pLabel1->setText(KviHtmlGenerator::convertToHtml(m_szText)); - m_pLabel1->setWordWrap(true); - m_pLabel1->setFont(KVI_OPTION_FONT(KviOption_fontNotifier)); - QPalette pal = m_pLabel1->palette(); - pal.setColor(QPalette::WindowText, KVI_OPTION_COLOR(KviOption_colorNotifierForeground)); - m_pLabel1->setPalette(pal); - - if(bShowImages) - { - m_pHBox->setStretch(1,99); - m_pHBox->addWidget(m_pLabel0); - } - m_pHBox->addWidget(m_pLabel1); -} diff --git a/src/modules/notifier/notifiermessage.h b/src/modules/notifier/notifiermessage.h deleted file mode 100644 index 518a15098..000000000 --- a/src/modules/notifier/notifiermessage.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef _NOTIFIERMESSAGE_H_ -#define _NOTIFIERMESSAGE_H_ -//============================================================================= -// -// File : notifiermessage.h -// Creation date : Mar 02 Nov 2004 02:41:18 by Iacopo Palazzi -// -// This file is part of the KVIrc distribution -// Copyright (C) 2004 Szymon Stefanek (pragma at kvirc dot net) -// Copyright (C) 2004-2008 Iacopo Palazzi < iakko(at)siena(dot)linux(dot)it > -// Copyright (C) 2009 Fabio Bas < ctrlaltca at gmail dot com > -// -// This program is FREE software. You can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include -#include -#include -#include -#include - -/** -* \class KviNotifierMessage -* \brief A single message in a notifier window -* -* This is basically a single message that can appear in a notifier window -* It's made up of an icon and a rich text content -* This class is basically a QLabel with a method that translates a raw irc message to html code. -*/ -class KviNotifierMessage : public QWidget -{ - friend class KviNotifierWindow; -public: - /** - * \brief Constructs the KviNotifierMessage object - * \param pPixmap pointer to a message icon, can be null - * \param szText const reference to message text in irc format - * \return KviNotifierMessage - */ - KviNotifierMessage(QPixmap * pPixmap, const QString &szText); - /** - * \brief Destroys the KviNotifierMessage object - */ - ~KviNotifierMessage(); -private: - /// The message text - QString m_szText; - /// The message icon (can be null) - QPixmap * m_pPixmap; - /// Layout for the labels - QHBoxLayout * m_pHBox; - /// Label for the message icon - QLabel * m_pLabel0; - /// Label for the message text - QLabel * m_pLabel1; -public: - /** - * \brief Returns the original irc message - * \return QString - */ - inline QString text() const { return m_szText; }; - /** - * \brief Returns the message icon - * \return QPixmap * - */ - inline QPixmap * pixmap() const { return m_pPixmap; }; - /** - * \brief Updates the aspect of this message - * \return void - */ - void updateGui(); -}; - -#endif //!_NOTIFIERMESSAGE_H_ diff --git a/src/modules/notifier/notifiersettings.h b/src/modules/notifier/notifiersettings.h deleted file mode 100644 index 1a0a29e42..000000000 --- a/src/modules/notifier/notifiersettings.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef _NOTIFIER_SETTINGS_H_ -#define _NOTIFIER_SETTINGS_H_ -//============================================================================= -// -// File : notifiersettings.h -// Creation date : Thu 30 Dev 2004 21:21:33 by Iacopo Palazzi -// -// This file is part of the Notifier - KVIrc Distribution distribution -// Copyright (C) 2004-2008 Iacopo Palazzi < iakko(at)siena(dot)linux(dot)it > -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -// Global settings for KviNotifier - - - -#define WDG_MIN_WIDTH 370 -#define WDG_MIN_HEIGHT 160 -#define WDG_BORDER_THICKNESS 5 -#define SPACING 2 - -#define WDG_ICON_OUT 0 -#define WDG_ICON_OVER 1 -#define WDG_ICON_CLICKED 2 -#define WDG_ICON_ON 3 -#define WDG_ICON_OFF 4 - -#define NTF_TABS_FONT_BASELINE 8 - -#define MAX_MESSAGES_IN_WINDOW 20 -// keep hidden messages for 600 seconds : 10 min -#define MAX_MESSAGE_LIFETIME 600 - -#define OPACITY_STEP 0.07 - -#define NUM_OLD_COLORS 6 - -#define WDG_UPSX 1 -#define WDG_UP 2 -#define WDG_UPDX 3 -#define WDG_DWNSX 4 -#define WDG_DWN 5 -#define WDG_DWNDX 6 -#define WDG_SX 7 -#define WDG_DX 8 - -#define m_mac_bkgColor QColor(236,233,216) // Light-brown color of notifier background widget - -enum State { Hidden, Showing, Visible, Hiding, FocusingOff, FocusingOn }; -enum TabState { Normal, Highlighted, Changed }; - -#endif //_NOTIFIER_SETTINGS_H_ diff --git a/src/modules/notifier/notifierwindow.cpp b/src/modules/notifier/notifierwindow.cpp deleted file mode 100644 index f46b87c2d..000000000 --- a/src/modules/notifier/notifierwindow.cpp +++ /dev/null @@ -1,1153 +0,0 @@ -//============================================================================= -// -// File : notifierwindow.cpp -// Creation date : Tue Jul 6 2004 20:25:12 CEST by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2004-2008 Iacopo Palazzi < iakko(at)siena.linux.it > -// -// This program is FREE software. You can redistribute it and/or -// modify it under the linkss of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= -#include "kvi_settings.h" - -#include "notifiermessage.h" -#include "notifierwindow.h" -#include "notifierwindowborder.h" -#include "notifierwindowtab.h" - -#include "KviIconManager.h" -#include "KviConfigurationFile.h" -#include "KviWindow.h" -#include "KviLocale.h" -#include "KviMainWindow.h" -#include "KviMircCntrl.h" -#include "KviOptions.h" -#include "KviUserInput.h" -#include "KviThemedLineEdit.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern KviNotifierWindow * g_pNotifierWindow; - -KviNotifierWindow::KviNotifierWindow() -: QWidget(0, -#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - Qt::FramelessWindowHint | - Qt::Tool | - Qt::WindowStaysOnTopHint) -#else - Qt::FramelessWindowHint | -#ifndef COMPILE_ON_MAC - Qt::Tool | - Qt::X11BypassWindowManagerHint | -#endif - Qt::WindowStaysOnTopHint) -#endif -{ - setObjectName("kvirc_notifier_window"); - - g_pNotifierWindow = this; - - m_eState = Hidden; - m_dOpacity = 0.0; - m_pShowHideTimer = 0; - m_pBlinkTimer = 0; - m_tAutoHideAt = 0; - m_tStartedAt=0; - m_pAutoHideTimer = 0; - - m_pWndBorder = new KviNotifierWindowBorder(); - - setFocusPolicy(Qt::NoFocus); - setMouseTracking(true); - setAutoFillBackground(true); - - hide(); - - m_bBlinkOn = false; - - m_bCloseDown = false; - m_bPrevDown = false; - m_bNextDown = false; - m_bWriteDown = false; - - m_bLeftButtonIsPressed = false; - m_bDiagonalResizing = false; - m_bResizing = false; - - m_pContextPopup = 0; - m_pDisablePopup = 0; - - m_bDragging = false; - - m_bDisableHideOnMainWindowGotAttention = false; - - // Positioning the notifier bottom-right - QDesktopWidget * pDesktop = QApplication::desktop(); - QRect r = pDesktop->availableGeometry(pDesktop->primaryScreen()); - - m_wndRect.setRect( - r.x() + r.width() - (WDG_MIN_WIDTH + SPACING), - r.y() + r.height() - (WDG_MIN_HEIGHT + SPACING), - WDG_MIN_WIDTH, - WDG_MIN_HEIGHT); - - m_pWndTabs = new QTabWidget(this); - m_pWndTabs->setUsesScrollButtons(true); - m_pWndTabs->setTabsClosable(true); - connect(m_pWndTabs,SIGNAL(tabCloseRequested(int)),this,SLOT(slotTabCloseRequested(int))); - - m_pProgressBar = new QProgressBar(this); - m_pProgressBar->setOrientation(Qt::Vertical); - m_pProgressBar->setRange(0, 100); - m_pProgressBar->setTextVisible(false); - m_pProgressBar->setMaximumWidth(8); - m_pProgressBar->installEventFilter(this); - - m_pLineEdit = new KviThemedLineEdit(this, 0, "notifier_lineedit"); - QPalette palette=m_pLineEdit->palette(); - palette.setColor(m_pLineEdit->backgroundRole(), Qt::transparent); - m_pLineEdit->setPalette(palette); - m_pLineEdit->installEventFilter(this); - connect(m_pLineEdit,SIGNAL(returnPressed()),this,SLOT(returnPressed())); - - QGridLayout *layout = new QGridLayout; - layout->addWidget(m_pProgressBar, 0,0,2,1); - layout->addWidget(m_pWndTabs,0,1,1,1); - layout->addWidget(m_pLineEdit,1,1,1,1); - layout->setSpacing(SPACING); - - layout->setGeometry(m_pWndBorder->bodyRect()); - layout->setContentsMargins(5,25,5,5); - setLayout(layout); - - connect(g_pApp,SIGNAL(updateNotifier()),this,SLOT(updateGui())); - QTimer::singleShot(0,this,SLOT(updateGui())); -} - -KviNotifierWindow::~KviNotifierWindow() -{ - stopShowHideTimer(); - stopBlinkTimer(); - stopAutoHideTimer(); - delete m_pWndBorder; - m_pWndTabs->deleteLater(); -} - -void KviNotifierWindow::updateGui() -{ - setFont(KVI_OPTION_FONT(KviOption_fontNotifier)); - QPalette palette=m_pLineEdit->palette(); - palette.setColor(m_pLineEdit->foregroundRole(), KVI_OPTION_COLOR(KviOption_colorNotifierForeground)); - m_pLineEdit->setPalette(palette); - m_pLineEdit->setFont(KVI_OPTION_FONT(KviOption_fontNotifier)); - - for(int i=0; icount();++i) - { - ((KviNotifierWindowTab*)m_pWndTabs->widget(i))->updateGui(); - } - -} - -void KviNotifierWindow::addMessage(KviWindow * pWnd, const QString & szImageId, const QString & szText, unsigned int uMessageTime) -{ - QPixmap * pIcon; - QString szMessage = szText; - szMessage.replace( QRegExp("\r([^\r])*\r([^\r])+\r"), "\\2" ); - if(szImageId.isEmpty()) - pIcon = 0; - else - pIcon = g_pIconManager->getImage(szImageId); - - KviNotifierMessage * pMessage = new KviNotifierMessage(pIcon ? new QPixmap(*pIcon) : 0,szMessage); - - //search for an existing tab - KviNotifierWindowTab * pTab = 0, * pTmp = 0; - for(int i=0; i < m_pWndTabs->count();++i) - { - pTmp = (KviNotifierWindowTab*)m_pWndTabs->widget(i); - if(pTmp->wnd() == pWnd) - { - pTab = pTmp; - break; - } - } - - if(!pTab) - { - pTab = new KviNotifierWindowTab(pWnd, m_pWndTabs); - } - - //if the notifier is already visible, don't steal the focus from the current tab! - //the user could be writing a message on it (bug #678) - if(!isVisible()) - m_pWndTabs->setCurrentWidget(pTab); - - pTab->appendMessage(pMessage); - - if(!isActiveWindow()) - startBlinking(); - - if(uMessageTime > 0) - { - kvi_time_t tAutoHide = kvi_unixTime() + uMessageTime; - if(m_tAutoHideAt < tAutoHide) - { - m_tAutoHideAt = tAutoHide; - if(m_eState == Visible) - startAutoHideTimer(); - } - } else { - // never hide - stopAutoHideTimer(); - m_tAutoHideAt = 0; - } - - if(pWnd) - { - if(pWnd->hasAttention()) - m_bDisableHideOnMainWindowGotAttention = true; - } - - if(isVisible()) - update(); -} - -void KviNotifierWindow::stopShowHideTimer() -{ - if(!m_pShowHideTimer) - return; - delete m_pShowHideTimer; - m_pShowHideTimer = 0; -} - -void KviNotifierWindow::stopBlinkTimer() -{ - if(!m_pBlinkTimer) - return; - delete m_pBlinkTimer; - m_pBlinkTimer = 0; -} - -void KviNotifierWindow::stopAutoHideTimer() -{ - if(!m_pAutoHideTimer) - return; - delete m_pAutoHideTimer; - m_pAutoHideTimer = 0; - m_pProgressBar->setValue(0); -} - -// FIXME: The code for detecting fullscreen window does NOT take into account multi-screen setups. -// We also lack the code for MacOSX and Qt-only-X11 compilation. - -#if COMPILE_KDE_SUPPORT - #include - - static bool active_window_is_full_screen() - { - WId activeId = KWindowSystem::activeWindow(); - KWindowInfo wi = KWindowSystem::windowInfo(activeId, NET::WMState); - return (wi.valid() && wi.hasState(NET::FullScreen)); - } -#else // COMPILE_KDE_SUPPORT - #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - - #include - - static bool active_window_is_full_screen() - { - HWND hForeground = ::GetForegroundWindow(); - if(!hForeground) - return false; - - HWND hDesktop = ::GetDesktopWindow(); - if(hForeground == hDesktop) - return false; - - HWND hShell = ::GetShellWindow(); - if(hForeground == hShell) - return false; - - RECT rct; - ::GetWindowRect(hForeground,&rct); - - if((rct.right - rct.left) < GetSystemMetrics(SM_CXSCREEN)) - return false; - - if((rct.bottom - rct.top) < GetSystemMetrics(SM_CYSCREEN)) - return false; - - return true; - } - - #endif //COMPILE_ON_WINDOWS || COMPILE_ON_MINGW -#endif // COMPILE_KDE_SUPPORT - -void KviNotifierWindow::doShow(bool bDoAnimate) -{ - if(!KVI_OPTION_BOOL(KviOption_boolEnableNotifier)) - return; - - kvi_time_t tNow = kvi_unixTime(); - if(g_tNotifierDisabledUntil > tNow) - return; - g_tNotifierDisabledUntil = 0; - -#if defined(COMPILE_KDE_SUPPORT) || defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) - if(KVI_OPTION_BOOL(KviOption_boolDontShowNotifierIfActiveWindowIsFullScreen)) - { - // check if the active window is full screen - if(active_window_is_full_screen()) - return; - } -#endif //COMPILE_KDE_SUPPORT || COMPILE_ON_WINDOWS || COMPILE_ON_MINGW - - switch(m_eState) - { - case Showing: - // already showing up - return; - break; - case Visible: - // already visible - return; - break; - case Hiding: - // ops.. hiding! - m_eState = Showing; - break; - case Hidden: - stopShowHideTimer(); - stopBlinkTimer(); - - m_bDragging = false; - m_bCloseDown = false; - m_bPrevDown = false; - m_bNextDown = false; - m_bWriteDown = false; - m_bBlinkOn = false; - if(bDoAnimate) - { - m_pShowHideTimer = new QTimer(); - connect(m_pShowHideTimer,SIGNAL(timeout()),this,SLOT(heartbeat())); - m_dOpacity = OPACITY_STEP; - m_eState = Showing; - m_bCrashShowWorkAround = true; - setWindowOpacity(m_dOpacity); - show(); - m_pShowHideTimer->start(40); - m_bCrashShowWorkAround = false; - } else { - m_dOpacity = 1.0; - m_eState = Visible; - show(); - startBlinking(); - startAutoHideTimer(); - } - break; - default: - break; - } -} - -bool KviNotifierWindow::shouldHideIfMainWindowGotAttention() -{ - if(m_bDisableHideOnMainWindowGotAttention) - return false; - KviNotifierWindowTab * pTab = (KviNotifierWindowTab *) m_pWndTabs->currentWidget(); - if(!pTab) - return false; - if(!pTab->wnd()) - return false; - return pTab->wnd()->hasAttention(); -} - -void KviNotifierWindow::heartbeat() -{ - bool bIncreasing; - double targetOpacity = 0; - switch(m_eState) - { - case Hidden: - hideNow(); - break; - case Visible: - stopShowHideTimer(); - m_dOpacity = 1.0; - if(!isVisible()) - show(); - else - update(); - break; - case Showing: - // if the main window got attention while - // showing up then just hide now - if(shouldHideIfMainWindowGotAttention()) - { - m_eState = Hiding; - } else { - m_dOpacity += OPACITY_STEP; - targetOpacity = isActiveWindow() ? KVI_OPTION_UINT(KviOption_uintNotifierActiveTransparency) : KVI_OPTION_UINT(KviOption_uintNotifierInactiveTransparency); - - targetOpacity/=100; - if(m_dOpacity >= targetOpacity) - { - m_dOpacity = targetOpacity; - m_eState = Visible; - stopShowHideTimer(); - startBlinking(); - startAutoHideTimer(); - } - - if(!isVisible()) - show(); - setWindowOpacity(m_dOpacity); - update(); - - } - break; - case FocusingOn: - targetOpacity = KVI_OPTION_UINT(KviOption_uintNotifierActiveTransparency); - targetOpacity /= 100; - bIncreasing = targetOpacity > m_dOpacity; - m_dOpacity += bIncreasing? - OPACITY_STEP : -(OPACITY_STEP); - if((bIncreasing && (m_dOpacity >= targetOpacity)) || - (!bIncreasing && (m_dOpacity <= targetOpacity)) - ) - { - m_dOpacity = targetOpacity; - m_eState = Visible; - stopShowHideTimer(); - } - - setWindowOpacity(m_dOpacity); - break; - case FocusingOff: - targetOpacity = KVI_OPTION_UINT(KviOption_uintNotifierInactiveTransparency); - targetOpacity /= 100; - bIncreasing = targetOpacity > m_dOpacity; - m_dOpacity += bIncreasing ? OPACITY_STEP : -(OPACITY_STEP); - //qDebug("%f %f %i %i",m_dOpacity,targetOpacity,bIncreasing,(m_dOpacity >= targetOpacity)); - if((bIncreasing && (m_dOpacity >= targetOpacity)) || - (!bIncreasing && (m_dOpacity <= targetOpacity)) - ) - { - m_dOpacity = targetOpacity; - m_eState = Visible; - stopShowHideTimer(); - } - - setWindowOpacity(m_dOpacity); - break; - case Hiding: - m_dOpacity -= OPACITY_STEP; - setWindowOpacity(m_dOpacity); - if(m_dOpacity <= 0.0) - hideNow(); - else - update(); - break; - } -} - -void KviNotifierWindow::hideNow() -{ - stopBlinkTimer(); - stopShowHideTimer(); - stopAutoHideTimer(); - m_eState = Hidden; - m_dOpacity = 0.0; - m_tAutoHideAt = 0; - hide(); -} - -void KviNotifierWindow::doHide(bool bDoAnimate) -{ - stopAutoHideTimer(); - switch(m_eState) - { - case Hiding: - // already hiding up - if(!bDoAnimate) - hideNow(); - return; - break; - case Hidden: - // already hidden - if(isVisible()) - hideNow(); - return; - break; - case Showing: - // ops.. hiding! - if(!bDoAnimate) - hideNow(); - else { - // continue animating, but hide - m_eState = Hiding; - } - break; - case Visible: - stopBlinkTimer(); - stopShowHideTimer(); - if((!bDoAnimate) || (x() != m_pWndBorder->x()) || (y() != m_pWndBorder->y())) - { - - //qDebug("just hide quickly with notifier x() %d and notifier y() % - WBorderx() %d and WBordery() %d and bDoanimate %d",x(),y(),m_pWndBorder->x(),m_pWndBorder->y(),bDoAnimate); - // the user asked to not animate or - // the window has been moved and the animation would suck anyway - // just hide quickly - hideNow(); - } else { - //qDebug("starting hide animation notifier x() %d and notifier y() % - WBorderx() %d and WBordery() %d and bDoanimate %d",x(),y(),m_pWndBorder->x(),m_pWndBorder->y(),bDoAnimate); - m_pShowHideTimer = new QTimer(); - connect(m_pShowHideTimer,SIGNAL(timeout()),this,SLOT(heartbeat())); - m_dOpacity = 1.0 - OPACITY_STEP; - m_eState = Hiding; - setWindowOpacity(m_dOpacity); - update(); - m_pShowHideTimer->start(40); - } - break; - default: - break; - } -} - -void KviNotifierWindow::showEvent(QShowEvent *) -{ - setGeometry(m_wndRect); -} - -void KviNotifierWindow::hideEvent(QHideEvent *) -{ - if(m_bCrashShowWorkAround) - return; - stopBlinkTimer(); - stopShowHideTimer(); - stopAutoHideTimer(); - m_eState = Hidden; // make sure it's true - m_tAutoHideAt = 0; // make sure it's true - m_bDisableHideOnMainWindowGotAttention = false; -} - -void KviNotifierWindow::startBlinking() -{ - stopBlinkTimer(); - m_bBlinkOn = false; - - if(KVI_OPTION_BOOL(KviOption_boolNotifierFlashing)) - { - m_pBlinkTimer = new QTimer(); - connect(m_pBlinkTimer,SIGNAL(timeout()),this,SLOT(blink())); - m_iBlinkCount = 0; - m_pBlinkTimer->start(1000); - } -} - -void KviNotifierWindow::startAutoHideTimer() -{ - stopAutoHideTimer(); - m_tStartedAt = kvi_unixTime(); - if(m_tAutoHideAt <= m_tStartedAt) - return; - - int iSecs = m_tAutoHideAt - m_tStartedAt; - if(iSecs < 5) - iSecs = 5; - m_pAutoHideTimer = new QTimer(); - - connect(m_pAutoHideTimer,SIGNAL(timeout()),this,SLOT(progressUpdate())); - m_pAutoHideTimer->start(100); -} - -void KviNotifierWindow::blink() -{ - m_iBlinkCount++; - m_bBlinkOn = !m_bBlinkOn; - - if(m_iBlinkCount > 100) - { - // stop blinking at a certain point and remain highlighted - m_bBlinkOn = true; - stopBlinkTimer(); - } else { - // if the main window got attention while - // showing up then just hide now - if(shouldHideIfMainWindowGotAttention()) - { - doHide(false); // don't animate: the background has almost surely changed - return; - } - } - update(); -} - -void KviNotifierWindow::paintEvent(QPaintEvent * e) -{ - QPainter * pPaint = new QPainter(this); - - if(m_wndRect.width() != m_pWndBorder->width() || m_wndRect.height() != m_pWndBorder->height()) - m_pWndBorder->resize(m_wndRect.size()); - - if(m_bBlinkOn) - { - m_pWndBorder->draw(pPaint,true); - } else { - m_pWndBorder->draw(pPaint); - } - - pPaint->setPen(KVI_OPTION_COLOR(KviOption_colorNotifierTitleForeground)); - pPaint->setFont(KVI_OPTION_FONT(KviOption_fontNotifierTitle)); - - QString szTitle = "KVIrc - "; - KviNotifierWindowTab * pTab = (KviNotifierWindowTab *)m_pWndTabs->currentWidget(); - if(pTab) - { - if(pTab->wnd()) - { - szTitle += pTab->wnd()->plainTextCaption(); - } else { - szTitle += "notifier"; - } - } else { - szTitle += "notifier"; - } - pPaint->drawText(m_pWndBorder->titleRect(),Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine,szTitle); - - delete pPaint; - e->ignore(); -} - -void KviNotifierWindow::mouseMoveEvent(QMouseEvent * e) -{ - if(!m_bLeftButtonIsPressed) - { - if(checkResizing(e->pos())) - goto sartelo; - - if(m_pWndBorder->captionRect().contains(e->pos())) - { - if(m_pWndBorder->closeRect().contains(e->pos())) - m_pWndBorder->setCloseIcon(WDG_ICON_OVER); - else - m_pWndBorder->setCloseIcon(WDG_ICON_OUT); - goto sartelo; - } - -sartelo: - update(); - } - - if(m_bDragging) - { - setCursor(Qt::SizeAllCursor); - - int iW = m_wndRect.width(); - int iH = m_wndRect.height(); - - m_wndRect.setX(m_pntPos.x() + cursor().pos().x() - m_pntDrag.x()); - m_wndRect.setY(m_pntPos.y() + cursor().pos().y() - m_pntDrag.y()); - - m_wndRect.setWidth(iW); - m_wndRect.setHeight(iH); - - setGeometry(m_wndRect); - } else if(m_bResizing) - { - resize(e->pos()); - } -} - -void KviNotifierWindow::mousePressEvent(QMouseEvent * e) -{ - // stop blinking first of all :) - bool bWasBlinkOn = m_bBlinkOn; - m_bBlinkOn = false; - stopBlinkTimer(); - m_tAutoHideAt = 0; - stopAutoHideTimer(); - - activateWindow(); - setFocus(); - - m_pntClick = e->pos(); - - if(e->button() == Qt::RightButton) - { - contextPopup(mapToGlobal(e->pos())); - return; - } else if(e->button() == Qt::LeftButton) - { - m_bLeftButtonIsPressed = true; - } - - if(checkResizing(m_pntClick)) - { - update(); - return; - } - - if(m_pWndBorder->captionRect().contains(e->pos())) - { - if(m_pWndBorder->closeRect().contains(e->pos())) - { - m_bCloseDown = true; - m_pWndBorder->setCloseIcon(WDG_ICON_CLICKED); - update(); - return; - } - - if(!m_bResizing) - { - m_bDragging = true; - m_pntDrag = cursor().pos(); - m_pntPos = pos(); - update(); - return; - } - } - - if(m_pWndBorder->rect().contains(e->pos()) || bWasBlinkOn) - update(); -} - -void KviNotifierWindow::mouseReleaseEvent(QMouseEvent * e) -{ - m_bWriteDown = false; - m_bNextDown = false; - m_bPrevDown = false; - m_bCloseDown = false; - m_bLeftButtonIsPressed = false; - m_bResizing = false; - - if(m_bDragging) - { - m_bDragging = false; - if(QApplication::overrideCursor()) - QApplication::restoreOverrideCursor(); - return; - } - - if(m_pWndBorder->captionRect().contains(e->pos())) - { - if(m_pWndBorder->closeRect().contains(e->pos())) - hideNow(); - else - update(); - } - - setCursor(-1); -} - -void KviNotifierWindow::keyPressEvent(QKeyEvent * e) -{ - if(e->key() == Qt::Key_Escape) - { - hideNow(); - return; - } -} - -bool KviNotifierWindow::checkResizing(QPoint e) -{ - if(e.y() < WDG_BORDER_THICKNESS) - { - if(e.x() < WDG_BORDER_THICKNESS) - { - //// UP LEFT CORNER //// - setCursor(Qt::SizeFDiagCursor); - if (m_bLeftButtonIsPressed) - { - m_bResizing = true; - m_whereResizing = WDG_UPSX; - } - } else if(e.x() > (size().width()-WDG_BORDER_THICKNESS)) - { - //// UP RIGHT CORNER //// - setCursor(Qt::SizeBDiagCursor); - if (m_bLeftButtonIsPressed) - { - m_bResizing = true; - m_whereResizing = WDG_UPDX; - } - } else { - //// UP SIDE //// - setCursor(Qt::SizeVerCursor); - if (m_bLeftButtonIsPressed) - { - m_bResizing = true; - m_whereResizing = WDG_UP; - } - } - } else if(e.y() > (size().height()-WDG_BORDER_THICKNESS)) - { - if(e.x() < WDG_BORDER_THICKNESS) - { - //// DOWN LEFT CORNER //// - setCursor(Qt::SizeBDiagCursor); - if(m_bLeftButtonIsPressed) - { - m_bResizing = true; - m_whereResizing = WDG_DWNSX; - } - } else if(e.x() > (size().width()-WDG_BORDER_THICKNESS)) - { - //// DOWN RIGHT CORNER //// - setCursor(Qt::SizeFDiagCursor); - if(m_bLeftButtonIsPressed) - { - m_bResizing = true; - m_whereResizing = WDG_DWNDX; - } - } else { - //// DOWN SIDE //// - setCursor(Qt::SizeVerCursor); - if(m_bLeftButtonIsPressed) - { - m_bResizing = true; - m_whereResizing = WDG_DWN; - } - } - } else { - if(e.x() < WDG_BORDER_THICKNESS) - { - //// LEFT SIZE //// - setCursor(Qt::SizeHorCursor); - if(m_bLeftButtonIsPressed) - { - m_bResizing = true; - m_whereResizing = WDG_SX; - } - } else if(e.x() > (size().width()-WDG_BORDER_THICKNESS)) - { - //// RIGHT SIZE //// - setCursor(Qt::SizeHorCursor); - if(m_bLeftButtonIsPressed) - { - m_bResizing = true; - m_whereResizing = WDG_DX; - } - } else { - //// ELSEWHERE //// - m_whereResizing = 0; - m_bResizing = false; - setCursor(-1); - } - } - return m_bResizing; -} - -void KviNotifierWindow::resize(QPoint, bool) -{ - if(m_whereResizing == WDG_UPSX || m_whereResizing == WDG_SX || m_whereResizing == WDG_DWNSX) - { - if((x() + width() - cursor().pos().x()) < WDG_MIN_WIDTH) - m_wndRect.setLeft(x() + width() - WDG_MIN_WIDTH); - else - m_wndRect.setLeft(cursor().pos().x()); - } - - if(m_whereResizing == WDG_UPSX || m_whereResizing == WDG_UP || m_whereResizing == WDG_UPDX) - { - if(y()+height()-cursor().pos().y() < WDG_MIN_HEIGHT) - m_wndRect.setTop(y() + height() - WDG_MIN_HEIGHT); - else - m_wndRect.setTop(cursor().pos().y()); - } - - if(m_whereResizing == WDG_DX || m_whereResizing == WDG_UPDX || m_whereResizing == WDG_DWNDX) - { - if((cursor().pos().x() - x()) > WDG_MIN_WIDTH) - m_wndRect.setRight(cursor().pos().x()); - else - m_wndRect.setRight(x() + WDG_MIN_WIDTH); - } - - if(m_whereResizing == WDG_DWN || m_whereResizing == WDG_DWNDX || m_whereResizing == WDG_DWNSX) - { - if((cursor().pos().y() - y()) > WDG_MIN_HEIGHT) - m_wndRect.setBottom(cursor().pos().y()); - else - m_wndRect.setBottom(y() + WDG_MIN_HEIGHT); - } - - showLineEdit(m_pLineEdit->isVisible()); - setGeometry(m_wndRect); -} - -inline void KviNotifierWindow::setCursor(int iCur) -{ - if(m_cursor.shape() != iCur) - { - if(QApplication::overrideCursor()) - QApplication::restoreOverrideCursor(); - m_cursor.setShape((Qt::CursorShape)iCur); - QApplication::setOverrideCursor(m_cursor); - } else if(iCur == -1) - { - if(QApplication::overrideCursor()) - QApplication::restoreOverrideCursor(); - } -} - -void KviNotifierWindow::enterEvent(QEvent *) -{ - if(!m_pShowHideTimer) - { - m_pShowHideTimer = new QTimer(); - connect(m_pShowHideTimer,SIGNAL(timeout()),this,SLOT(heartbeat())); - } - m_eState = FocusingOn; - m_pShowHideTimer->start(40); -} - -void KviNotifierWindow::leaveEvent(QEvent *) -{ - // Leaving the widget area, restore default cursor - m_pWndBorder->resetIcons(); - if(!m_bResizing) - setCursor(-1); - - if(!m_pShowHideTimer) - { - m_pShowHideTimer = new QTimer(); - connect(m_pShowHideTimer,SIGNAL(timeout()),this,SLOT(heartbeat())); - } - - if(m_eState!=Hidden) - { - m_eState = FocusingOff; - m_pShowHideTimer->start(40); - } -} - -void KviNotifierWindow::contextPopup(const QPoint & pos) -{ - if(!m_pContextPopup) - { - m_pContextPopup = new KviTalPopupMenu(this); - connect(m_pContextPopup,SIGNAL(aboutToShow()),this,SLOT(fillContextPopup())); - m_pDisablePopup = new KviTalPopupMenu(this); - } - - m_pContextPopup->popup(pos); -} - -void KviNotifierWindow::fillContextPopup() -{ - m_pContextPopup->clear(); - m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_EDITOR)),__tr2qs_ctx("Show/Hide input line","notifier"),this,SLOT(toggleLineEdit())); - m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CLOSE)),__tr2qs_ctx("Hide","notifier"),this,SLOT(hideNow())); - m_pContextPopup->insertSeparator(); - m_pDisablePopup->clear(); - m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),__tr2qs_ctx("1 Minute","notifier"),this,SLOT(disableFor1Minute())); - m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),__tr2qs_ctx("5 Minutes","notifier"),this,SLOT(disableFor5Minutes())); - m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),__tr2qs_ctx("15 Minutes","notifier"),this,SLOT(disableFor15Minutes())); - m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),__tr2qs_ctx("30 Minutes","notifier"),this,SLOT(disableFor30Minutes())); - m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),__tr2qs_ctx("1 Hour","notifier"),this,SLOT(disableFor60Minutes())); - m_pDisablePopup->insertSeparator(); - m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),__tr2qs_ctx("Until KVIrc is Restarted","notifier"),this,SLOT(disableUntilKVIrcRestarted())); - m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),__tr2qs_ctx("Permanently (Until Explicitly Enabled)","notifier"),this,SLOT(disablePermanently())); - - m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),__tr2qs_ctx("Disable","notifier"),m_pDisablePopup); -} - -void KviNotifierWindow::disableFor15Minutes() -{ - kvi_time_t tNow = kvi_unixTime(); - g_tNotifierDisabledUntil = tNow + (60 * 15); - - hideNow(); -} - -void KviNotifierWindow::disableFor5Minutes() -{ - kvi_time_t tNow = kvi_unixTime(); - g_tNotifierDisabledUntil = tNow + (60 * 5); - - hideNow(); -} - - -void KviNotifierWindow::disableFor1Minute() -{ - kvi_time_t tNow = kvi_unixTime(); - g_tNotifierDisabledUntil = tNow + 60; - - hideNow(); -} - -void KviNotifierWindow::disableFor30Minutes() -{ - kvi_time_t tNow = kvi_unixTime(); - g_tNotifierDisabledUntil = tNow + (60 * 30); - - hideNow(); -} - -void KviNotifierWindow::disableFor60Minutes() -{ - kvi_time_t tNow = kvi_unixTime(); - g_tNotifierDisabledUntil = tNow + (60 * 60); - - hideNow(); -} - -void KviNotifierWindow::disableUntilKVIrcRestarted() -{ - kvi_time_t tNow = kvi_unixTime(); - // in fact we just disable for one year - g_tNotifierDisabledUntil = tNow + (3600 * 24 * 360); // one year :D - // this will NOT work if the module is forcibly unloaded with /notifier.unload - // but the user should never do it :D - hideNow(); -} - -void KviNotifierWindow::disablePermanently() -{ - KVI_OPTION_BOOL(KviOption_boolEnableNotifier) = false; - hideNow(); -} - -void KviNotifierWindow::toggleLineEdit() -{ - showLineEdit(!m_pLineEdit->isVisible()); -} - -void KviNotifierWindow::showLineEdit(bool bShow) -{ - if(bShow) - { - if(m_pLineEdit->isVisible()) - return; - if(!((KviNotifierWindowTab *)m_pWndTabs->currentWidget())->wnd()) - return; - m_pLineEdit->setToolTip(""); - - QString szTip = __tr2qs_ctx("Write text or commands to window","notifier"); - szTip += " \""; - szTip += ((KviNotifierWindowTab *)m_pWndTabs->currentWidget())->wnd()->plainTextCaption(); - szTip += "\""; - m_pLineEdit->setToolTip(szTip); - m_pLineEdit->show(); - m_pLineEdit->setFocus(); - activateWindow(); - } else { - if(!m_pLineEdit->isVisible()) - return; - m_pLineEdit->hide(); - setFocus(); - update(); - } -} - -bool KviNotifierWindow::eventFilter(QObject * pEdit, QEvent * e) -{ - if(pEdit != (QObject *)m_pLineEdit) - return false; // huh ? - if(!m_pLineEdit->isVisible()) - return false; - if(e->type() == QEvent::MouseButtonPress) - { - bool bWasBlinkOn = m_bBlinkOn; - m_bBlinkOn = false; - m_tAutoHideAt = 0; - stopAutoHideTimer(); - stopBlinkTimer(); - activateWindow(); - m_pLineEdit->setFocus(); - if(bWasBlinkOn) - update(); - return true; - } - if(e->type() == QEvent::KeyPress) - { - if(((QKeyEvent *)e)->key() == Qt::Key_Escape) - { - hideNow(); - return true; - } - } - return false; -} - -void KviNotifierWindow::returnPressed() -{ - if(!m_pLineEdit->isVisible()) - return; - - KviNotifierWindowTab * pTab = (KviNotifierWindowTab *) m_pWndTabs->currentWidget(); - if(!pTab) - return; - if(!pTab->wnd()) - return; - - QString szTxt = m_pLineEdit->text(); - if(szTxt.isEmpty()) - return; - QString szHtml = szTxt; - szHtml.replace("<","<"); - szHtml.replace(">",">"); - KviCString szTmp(KviCString::Format,"%d",KVI_SMALLICON_OWNPRIVMSG); - - addMessage(pTab->wnd(),szTmp.ptr(),szHtml,0); - m_pLineEdit->setText(""); - KviUserInput::parse(szTxt,pTab->wnd(),QString(),1); -} - -void KviNotifierWindow::progressUpdate() -{ - kvi_time_t now = kvi_unixTime(); - int iProgress = (int)(100/(m_tAutoHideAt - m_tStartedAt)*(now - m_tStartedAt)); - m_pProgressBar->setValue(iProgress); - if(now >= m_tAutoHideAt) - { - m_tAutoHideAt = 0; - stopAutoHideTimer(); - doHide(true); - } -} - -void KviNotifierWindow::slotTabCloseRequested(int iIndex) -{ - if(m_pWndTabs) - { - KviNotifierWindowTab * pTab = (KviNotifierWindowTab *) m_pWndTabs->widget(iIndex); - m_pWndTabs->removeTab(iIndex); - if(pTab) - pTab->deleteLater(); - - if(m_pWndTabs->count()==0) - hideNow(); - } -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_notifierwindow.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/notifier/notifierwindow.h b/src/modules/notifier/notifierwindow.h deleted file mode 100644 index 10e1b8c6a..000000000 --- a/src/modules/notifier/notifierwindow.h +++ /dev/null @@ -1,159 +0,0 @@ -#ifndef _NOTIFIERWINDOW_H_ -#define _NOTIFIERWINDOW_H_ -//============================================================================= -// -// File : notifierwindow.h -// Creation date : Tue Jul 6 2004 20:25:12 CEST by Szymon Stefanek -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2004 Szymon Stefanek (pragma at kvirc dot net) -// Copyright (C) 2005-2008 Iacopo Palazzi < iakko(at)siena(dot)linux(dot)it > -// -// This program is FREE software. You can redistribute it and/or -// modify it under the linkss of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "notifiersettings.h" - -#include "kvi_settings.h" -#include "KviQString.h" -#include "KviPointerList.h" -#include "KviTalPopupMenu.h" -#include "KviTimeUtils.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class QPainter; -class KviWindow; -class KviNotifierMessage; -class KviNotifierWindowBorder; -class KviNotifierWindowTabs; -class KviThemedLineEdit; - -extern kvi_time_t g_tNotifierDisabledUntil; - -class KviNotifierWindow : public QWidget -{ - Q_OBJECT -public: - KviNotifierWindow(); - ~KviNotifierWindow(); -protected: - QTimer * m_pShowHideTimer; - QTimer * m_pBlinkTimer; - QTimer * m_pAutoHideTimer; - State m_eState; - bool m_bBlinkOn; - double m_dOpacity; - - bool m_bCloseDown; - bool m_bPrevDown; - bool m_bNextDown; - bool m_bWriteDown; - bool m_bCrashShowWorkAround; - - QRect m_wndRect; - - KviNotifierMessage * m_pCurrentMessage; - KviThemedLineEdit * m_pLineEdit; - - bool m_bDragging; - bool m_bLeftButtonIsPressed; - bool m_bDiagonalResizing; - bool m_bResizing; - - int m_whereResizing; - - QPoint m_pntDrag; - QPoint m_pntPos; - QPoint m_pntClick; - int m_iBlinkCount; - KviTalPopupMenu * m_pContextPopup; - KviTalPopupMenu * m_pDisablePopup; - KviWindow * m_pWindowToRaise; - kvi_time_t m_tAutoHideAt; - kvi_time_t m_tStartedAt; - QTime m_qtStartedAt; - bool m_bDisableHideOnMainWindowGotAttention; - - QCursor m_cursor; - - QTabWidget * m_pWndTabs; - QProgressBar * m_pProgressBar; - KviNotifierWindowBorder * m_pWndBorder; -public: - void doShow(bool bDoAnimate); - void doHide(bool bDoAnimate); - int textWidth(); - void addMessage(KviWindow * pWnd,const QString &szImageId,const QString &szText,unsigned int uMessageTime); - void setDisableHideOnMainWindowGotAttention(bool b){ m_bDisableHideOnMainWindowGotAttention = b; }; - void showLineEdit(bool bShow); - inline int countTabs() const { if(m_pWndTabs)return m_pWndTabs->count(); return 0; }; - inline State state() const { return m_eState; }; -protected: - virtual void showEvent(QShowEvent *e); - virtual void hideEvent(QHideEvent * e); - virtual void paintEvent(QPaintEvent * e); - virtual void mousePressEvent(QMouseEvent * e); - virtual void mouseReleaseEvent(QMouseEvent * e); - virtual void mouseMoveEvent(QMouseEvent * e); - virtual void leaveEvent(QEvent * e); - virtual void enterEvent(QEvent * e); - virtual bool eventFilter(QObject * pEdit,QEvent * e); - virtual void keyPressEvent ( QKeyEvent * e ); -public slots: - void hideNow(); - void toggleLineEdit(); - void slotTabCloseRequested(int index); -protected slots: - void blink(); - void heartbeat(); - void returnPressed(); - void updateGui(); - void fillContextPopup(); - void disableFor1Minute(); - void disableFor5Minutes(); - void disableFor15Minutes(); - void disableFor30Minutes(); - void disableFor60Minutes(); - void disableUntilKVIrcRestarted(); - void disablePermanently(); - void progressUpdate(); -private: - void contextPopup(const QPoint &pos); - void startBlinking(); -// void computeRect(); - void stopShowHideTimer(); - void stopBlinkTimer(); - void stopAutoHideTimer(); - void startAutoHideTimer(); - bool shouldHideIfMainWindowGotAttention(); - void setCursor(int); - void resize(QPoint p, bool = true); - void redrawText(); - bool checkResizing(QPoint); -}; - -#endif //_NOTIFIERWINDOW_H_ diff --git a/src/modules/notifier/notifierwindowborder.cpp b/src/modules/notifier/notifierwindowborder.cpp deleted file mode 100644 index c8c94c3f5..000000000 --- a/src/modules/notifier/notifierwindowborder.cpp +++ /dev/null @@ -1,205 +0,0 @@ -//============================================================================= -// -// File : notifierwindowborder.cpp -// Creation date : Mon 03 Jan 2005 02:27:22 by Iacopo Palazzi -// -// This file is part of the KVIrc distribution -// Copyright (C) 2005-2008 Iacopo Palazzi < iakko(at)siena(dot)linux(dot)it > -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "notifierwindowborder.h" -#include "notifierwindowtab.h" - -#include "KviIconManager.h" - -#include - -KviNotifierWindowBorder::KviNotifierWindowBorder(QSize s) -{ - loadImages(); - resize(s); -} - -KviNotifierWindowBorder::~KviNotifierWindowBorder() -{ -} - -void KviNotifierWindowBorder::loadImages() -{ - // Normal Border - - QPixmap * p; - - if((p = g_pIconManager->getPixmap("notifier_pix_wnd_sx.png"))) - m_pixSX_N = *p; - if((p = g_pIconManager->getPixmap("notifier_pix_wnd_dx.png"))) - m_pixDX_N = *p; - if((p = g_pIconManager->getPixmap("notifier_pix_wnd_dwn.png"))) - m_pixDWN_N = *p; - if((p = g_pIconManager->getPixmap("notifier_pix_wnd_dwndx.png"))) - m_pixDWNDX_N = *p; - if((p = g_pIconManager->getPixmap("notifier_pix_wnd_dwnsx.png"))) - m_pixDWNSX_N = *p; - if((p = g_pIconManager->getPixmap("notifier_pix_caption_sx.png"))) - m_pixCaptionSX_N = *p; - if((p = g_pIconManager->getPixmap("notifier_pix_caption_dx.png"))) - m_pixCaptionDX_N = *p; - if((p = g_pIconManager->getPixmap("notifier_pix_caption_bkg.png"))) - m_pixCaptionBKG_N = *p; - - if((p = g_pIconManager->getPixmap("notifier_icon_close_out.png"))) - m_pixIconClose_out_N = *p; - if((p = g_pIconManager->getPixmap("notifier_icon_close_over.png"))) - m_pixIconClose_over_N = *p; - if((p = g_pIconManager->getPixmap("notifier_icon_close_clicked.png"))) - m_pixIconClose_clicked_N = *p; - - // Highlighted Border - - if((p = g_pIconManager->getPixmap("notifier_pix_wnd_sx_hl.png"))) - m_pixSX_HL = *p; - if((p = g_pIconManager->getPixmap("notifier_pix_wnd_dx_hl.png"))) - m_pixDX_HL = *p; - if((p = g_pIconManager->getPixmap("notifier_pix_wnd_dwn_hl.png"))) - m_pixDWN_HL = *p; - if((p = g_pIconManager->getPixmap("notifier_pix_wnd_dwndx_hl.png"))) - m_pixDWNDX_HL = *p; - if((p = g_pIconManager->getPixmap("notifier_pix_wnd_dwnsx_hl.png"))) - m_pixDWNSX_HL = *p; - if((p = g_pIconManager->getPixmap("notifier_pix_caption_sx_hl.png"))) - m_pixCaptionSX_HL = *p; - if((p = g_pIconManager->getPixmap("notifier_pix_caption_dx_hl.png"))) - m_pixCaptionDX_HL = *p; - if((p = g_pIconManager->getPixmap("notifier_pix_caption_bkg_hl.png"))) - m_pixCaptionBKG_HL = *p; - - if((p = g_pIconManager->getPixmap("notifier_icon_close_out_hl.png"))) - m_pixIconClose_out_HL = *p; - if((p = g_pIconManager->getPixmap("notifier_icon_close_over_hl.png"))) - m_pixIconClose_over_HL = *p; - if((p = g_pIconManager->getPixmap("notifier_icon_close_clicked_hl.png"))) - m_pixIconClose_clicked_HL = *p; - - setPics(); - setCloseIcon(WDG_ICON_OUT); - - if ( m_pixCaptionDX->height()==m_pixCaptionSX->height() && m_pixCaptionDX->height()==m_pixCaptionBKG->height()) // just to be sure that the height is fitting - m_captionRect.setHeight(m_pixCaptionDX->height()); - -} - -void KviNotifierWindowBorder::setPics(bool b) -{ - if (b) { - m_pixSX = &m_pixSX_HL; - m_pixDX = &m_pixDX_HL; - m_pixDWN = &m_pixDWN_HL; - m_pixDWNSX = &m_pixDWNSX_HL; - m_pixDWNDX = &m_pixDWNDX_HL; - m_pixCaptionSX = &m_pixCaptionSX_HL; - m_pixCaptionDX = &m_pixCaptionDX_HL; - m_pixCaptionBKG = &m_pixCaptionBKG_HL; - m_pixIconClose_out = &m_pixIconClose_out_HL; - m_pixIconClose_over = &m_pixIconClose_over_HL; - m_pixIconClose_clicked = &m_pixIconClose_clicked_HL; - } else { - m_pixSX = &m_pixSX_N; - m_pixDX = &m_pixDX_N; - m_pixDWN = &m_pixDWN_N; - m_pixDWNSX = &m_pixDWNSX_N; - m_pixDWNDX = &m_pixDWNDX_N; - m_pixCaptionSX = &m_pixCaptionSX_N; - m_pixCaptionDX = &m_pixCaptionDX_N; - m_pixCaptionBKG = &m_pixCaptionBKG_N; - m_pixIconClose_out = &m_pixIconClose_out_N; - m_pixIconClose_over = &m_pixIconClose_over_N; - m_pixIconClose_clicked = &m_pixIconClose_clicked_N; - } -} - -void KviNotifierWindowBorder::setWidth(int w) -{ - m_iRctWidth = w; - recalculatePositions(); -} - -void KviNotifierWindowBorder::setHeight(int h) -{ - m_iRctHeight = h; - recalculatePositions(); -} - -void KviNotifierWindowBorder::recalculatePositions() -{ - m_rct.setHeight(m_iRctHeight); - m_rct.setWidth(m_iRctWidth); - m_rct.setTopLeft(QPoint(0,0)); - - m_closeIconRect.setX(m_rct.width()-m_pixCaptionDX->width()-m_pixIconClose->width()); - m_closeIconRect.setY(2); - m_closeIconRect.setWidth(m_pixIconClose->width()); - m_closeIconRect.setHeight(m_pixIconClose->height()); - - m_captionRect.setTopLeft( m_rct.topLeft() ); - m_captionRect.setSize( QSize(m_rct.width(),m_pixCaptionDX->height()) ); - - m_bodyRect.setTopLeft( QPoint(m_pixCaptionDX->width(),m_captionRect.height()) ); - m_bodyRect.setSize( QSize(m_captionRect.width()-(2*m_pixCaptionDX->width()),m_rct.height()-m_captionRect.height()-m_pixDWN->height()) ); - - m_titleRect.setTopLeft( QPoint(m_pixCaptionSX->width(),0) ); - m_titleRect.setSize( QSize(m_rct.width()-m_pixCaptionSX->width()-m_pixCaptionDX->width()-m_pixIconClose->width(),m_captionRect.height())); - -} - -void KviNotifierWindowBorder::setCloseIcon(int state) -{ - m_eIconState = state; - switch (m_eIconState) { - case WDG_ICON_OUT: m_pixIconClose = m_pixIconClose_out; break; - case WDG_ICON_OVER: m_pixIconClose = m_pixIconClose_over; break; - case WDG_ICON_CLICKED: m_pixIconClose = m_pixIconClose_clicked; break; - }; -} - -void KviNotifierWindowBorder::resetIcons() -{ - setCloseIcon(WDG_ICON_OUT); -} - -void KviNotifierWindowBorder::draw(QPainter * p, bool b) -{ - setPics(b); - setCloseIcon(m_eIconState); - - // Draw the caption - p->drawPixmap(m_captionRect.x(), m_captionRect.y(), *m_pixCaptionSX); - p->drawTiledPixmap(m_pixCaptionSX->width(), 0, m_captionRect.width() - (m_pixCaptionSX->width() + m_pixCaptionDX->width()), m_captionRect.height(), *m_pixCaptionBKG); - p->drawPixmap(m_captionRect.width() - m_pixCaptionDX->width(), 0, *m_pixCaptionDX); - - // Draw the tiled borders - p->drawTiledPixmap(0, m_captionRect.height(), m_pixSX->width(), m_bodyRect.height(), *m_pixSX); - p->drawTiledPixmap(m_bodyRect.width() + m_bodyRect.x(), m_captionRect.height(), m_pixDX->width(), m_bodyRect.height(), *m_pixDX); - p->drawTiledPixmap(m_pixDWNSX->width(), m_captionRect.height() + m_bodyRect.height(), m_bodyRect.width() + 1, m_pixDWN->height(), *m_pixDWN); - - // Draw down corners - p->drawPixmap(0, m_captionRect.height() + m_bodyRect.height(), *m_pixDWNSX); - p->drawPixmap(m_bodyRect.width() + m_bodyRect.x(), m_captionRect.height() + m_bodyRect.height(), *m_pixDWNDX); - - //Drawing icons - p->drawPixmap(m_closeIconRect.x(), m_closeIconRect.y(), *m_pixIconClose); -} diff --git a/src/modules/notifier/notifierwindowborder.h b/src/modules/notifier/notifierwindowborder.h deleted file mode 100644 index d5a6bbcb0..000000000 --- a/src/modules/notifier/notifierwindowborder.h +++ /dev/null @@ -1,130 +0,0 @@ -#ifndef _KVINOTIFIERWINDOWBORDER_H_ -#define _KVINOTIFIERWINDOWBORDER_H_ -//============================================================================= -// -// File : notifierwindowborder.h -// Creation date : Mon 03 Jan 2005 02:27:22 by Iacopo Palazzi -// -// This file is part of the KVIrc distribution -// Copyright (C) 2005-2008 Iacopo Palazzi < iakko(at)siena(dot)linux(dot)it > -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "notifiersettings.h" - -#include -#include -#include - -class QPainter; - -class KviNotifierWindowBorder -{ -public: - KviNotifierWindowBorder(QSize = QSize(WDG_MIN_WIDTH,WDG_MIN_HEIGHT)); - ~KviNotifierWindowBorder(); - -// ================================ -// Put members declaration below... -// ================================ -private: - QRect m_rct; - QPoint m_pnt; - - QRect m_closeIconRect; - - QRect m_captionRect; - QRect m_bodyRect; - QRect m_titleRect; - - // Pictures - QPixmap * m_pixSX; - QPixmap * m_pixDX; - QPixmap * m_pixDWN; - QPixmap * m_pixDWNSX; - QPixmap * m_pixDWNDX; - QPixmap * m_pixCaptionSX; - QPixmap * m_pixCaptionDX; - QPixmap * m_pixCaptionBKG; - QPixmap * m_pixIconClose_out; - QPixmap * m_pixIconClose_over; - QPixmap * m_pixIconClose_clicked; - QPixmap * m_pixIconClose; - - QPixmap m_pixSX_N; - QPixmap m_pixDX_N; - QPixmap m_pixDWN_N; - QPixmap m_pixDWNSX_N; - QPixmap m_pixDWNDX_N; - QPixmap m_pixCaptionSX_N; - QPixmap m_pixCaptionDX_N; - QPixmap m_pixCaptionBKG_N; - QPixmap m_pixIconClose_out_N; - QPixmap m_pixIconClose_over_N; - QPixmap m_pixIconClose_clicked_N; - - QPixmap m_pixSX_HL; - QPixmap m_pixDX_HL; - QPixmap m_pixDWN_HL; - QPixmap m_pixDWNSX_HL; - QPixmap m_pixDWNDX_HL; - QPixmap m_pixCaptionSX_HL; - QPixmap m_pixCaptionDX_HL; - QPixmap m_pixCaptionBKG_HL; - QPixmap m_pixIconClose_out_HL; - QPixmap m_pixIconClose_over_HL; - QPixmap m_pixIconClose_clicked_HL; - - int m_eIconState; - int m_iRctWidth; - int m_iRctHeight; -private: - void loadImages(); - void recalculatePositions(); - -public: - // reading methods... - void setWidth(int w); - void setHeight(int h); - void resize(int w, int h) { setWidth(w); setHeight(h); }; - void resize(QSize r) { setWidth(r.width()); setHeight(r.height()); }; - void setGeometry(QRect r) { r.topLeft(); r.size(); /*qDebug("x,y: %d,%d", r.x(), r.y()); qDebug("w,h: %d,%d", r.width(), r.height());*/ }; - void setGeometry(QPoint p, QSize s) { setPoint (p.x(), p.y()); setWidth (s.width()); setHeight (s.height()); }; - - void setPoint(int x, int y) { m_pnt.setX(x); m_pnt.setY(y); m_rct.setX(x); m_rct.setY(y); }; - - void setCloseIcon(int state); - void resetIcons(); - - // writing methods... - inline int x() const { return m_pnt.x(); }; - inline int y() const { return m_pnt.y(); }; - inline int width() const { return m_rct.width(); }; - inline int height() const { return m_rct.height(); }; - inline int baseLine() const { return (y()+height()); }; - - inline QRect bodyRect() const { return m_bodyRect; }; - inline QRect captionRect() const { return m_captionRect; }; - inline QRect rect() const { return m_rct; }; - inline QRect closeRect() const { return m_closeIconRect; }; - inline QRect titleRect() const { return m_titleRect; }; - - void draw(QPainter *, bool b = false); - void setPics(bool b = false); -}; - -#endif //!_KVINOTIFIERWINDOWBORDER_H_ diff --git a/src/modules/notifier/notifierwindowtab.cpp b/src/modules/notifier/notifierwindowtab.cpp deleted file mode 100644 index 7f48d15f6..000000000 --- a/src/modules/notifier/notifierwindowtab.cpp +++ /dev/null @@ -1,230 +0,0 @@ -//============================================================================= -// -// File : notifierwindowtab.cpp -// File : notifierwindowtab.h -// Creation date : Tue 07 Jul 2009 10:28 by Fabio Bas -// -// This file is part of the KVIrc distribution -// Copyright (C) 2009 Fabio Bas < ctrlaltca at gmail dot com > -// -// This program is FREE software. You can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "notifiermessage.h" -#include "notifierwindowtab.h" -#include "notifierwindow.h" -#include "notifiersettings.h" - -#include "KviApplication.h" -#include "KviConfigurationFile.h" -#include "KviLocale.h" -#include "KviMainWindow.h" -#include "KviOptions.h" -#include "KviPixmapUtils.h" -#include "KviWindow.h" - -#include -#include -#include -#include -#include -#include - -#ifdef COMPILE_PSEUDO_TRANSPARENCY - #include - extern KVIRC_API QPixmap * g_pShadedChildGlobalDesktopBackground; -#endif - -extern KviNotifierWindow * g_pNotifierWindow; - -KviNotifierWindowTab::KviNotifierWindowTab(KviWindow * pWnd, QTabWidget * pParent) -: QScrollArea(pParent) -{ - m_pWnd = pWnd; - if(m_pWnd) - { - m_szLabel = m_pWnd->windowName(); - connect(pWnd,SIGNAL(windowNameChanged()),this,SLOT(labelChanged())); - connect(pWnd,SIGNAL(destroyed()),this,SLOT(closeMe())); - } else { - m_szLabel = "----"; - } - - if(pParent) - { - m_pParent = pParent; - m_pParent->addTab(this, m_szLabel); - } - - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); - - if(verticalScrollBar()) - connect(verticalScrollBar(),SIGNAL(rangeChanged(int, int)),this, SLOT(scrollRangeChanged(int, int))); - - QPalette pal = palette(); - pal.setColor(backgroundRole(), Qt::transparent); - setPalette(pal); - - m_pVWidget = new QWidget(viewport()); - m_pVBox = new QVBoxLayout(m_pVWidget); - m_pVBox->setSizeConstraint(QLayout::SetFixedSize); - m_pVBox->setSpacing(SPACING); - m_pVBox->setMargin(SPACING); - - setWidget(m_pVWidget); -} - -KviNotifierWindowTab::~KviNotifierWindowTab() -{ - if(m_pVBox) - m_pVBox->deleteLater(); - if(m_pVWidget) - m_pVWidget->deleteLater(); -} - -void KviNotifierWindowTab::appendMessage(KviNotifierMessage * pMessage) -{ - m_pVBox->addWidget(pMessage); - pMessage->setFixedWidth(viewport()->width()); - - while(m_pVBox->count() > MAX_MESSAGES_IN_WINDOW) - { - QLayoutItem * pTmp = m_pVBox->takeAt(0); - KviNotifierMessage * pTmp2 = (KviNotifierMessage*)pTmp->widget(); - if(pTmp2) - pTmp2->deleteLater(); - } -} - -void KviNotifierWindowTab::updateGui() -{ - for(int i=0; icount(); ++i) - { - QLayoutItem * pTmp = m_pVBox->itemAt(i); - KviNotifierMessage * pTmp2 = (KviNotifierMessage*)pTmp->widget(); - if(pTmp2) - pTmp2->updateGui(); - } -} - -void KviNotifierWindowTab::scrollRangeChanged(int, int) -{ - //this is the autoscroll - if(verticalScrollBar()) - verticalScrollBar()->triggerAction(QAbstractSlider::SliderToMaximum); -} - -void KviNotifierWindowTab::labelChanged() -{ - if(!m_pWnd || !m_pParent) - return; - - int iIdx = m_pParent->indexOf(this); - m_szLabel = m_pWnd->windowName(); - if(iIdx > -1) - m_pParent->setTabText(iIdx, m_szLabel); -} - -void KviNotifierWindowTab::mouseDoubleClickEvent(QMouseEvent *) -{ - if(!m_pWnd || !g_pNotifierWindow) - return; - if(!g_pApp->windowExists(m_pWnd)) - return; - - g_pNotifierWindow->hideNow(); - - if(m_pWnd->mdiParent()) - { - m_pWnd->frame()->raise(); - m_pWnd->frame()->setFocus(); - m_pWnd->frame()->setWindowState((m_pWnd->frame()->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); - if(!m_pWnd->frame()->isVisible()) - m_pWnd->frame()->show(); - } - - m_pWnd->frame()->setActiveWindow(m_pWnd); -} - -void KviNotifierWindowTab::closeMe() -{ - //our window has been closed - if(m_pParent && g_pNotifierWindow) - { - int iIdx = m_pParent->indexOf(this); - if(iIdx != -1) - { - g_pNotifierWindow->slotTabCloseRequested(iIdx); - } - } -} - -void KviNotifierWindowTab::resizeEvent(QResizeEvent *) -{ - if(m_pVBox) - { - int iWidth = viewport()->width(); - KviNotifierMessage * pMessage; - for(int i=0; i < m_pVBox->count(); i++) - { - pMessage = (KviNotifierMessage *)m_pVBox->itemAt(i)->widget(); - if(pMessage) - pMessage->setFixedWidth(iWidth); - } - } -} - -void KviNotifierWindowTab::paintEvent(QPaintEvent * e) -{ - QPainter * pPainter = new QPainter(viewport()); - - //make sure you clean your widget with a transparent - // color before doing any rendering - // note the usage of a composition mode Source - // it's important! - - #ifdef COMPILE_PSEUDO_TRANSPARENCY - if(KVI_OPTION_BOOL(KviOption_boolUseCompositingForTransparency) && g_pApp->supportsCompositing()) - { - pPainter->save(); - pPainter->setCompositionMode(QPainter::CompositionMode_Source); - QColor col = KVI_OPTION_COLOR(KviOption_colorGlobalTransparencyFade); - col.setAlphaF((float)((float)KVI_OPTION_UINT(KviOption_uintGlobalTransparencyChildFadeFactor) / (float)100)); - pPainter->fillRect(e->rect(), col); - pPainter->restore(); - } else if(g_pShadedChildGlobalDesktopBackground) - { - QPoint pnt = mapToGlobal(e->rect().topLeft()); - pPainter->drawTiledPixmap(e->rect(),*(g_pShadedChildGlobalDesktopBackground), pnt); - } else { - #endif - QPixmap * pPix = KVI_OPTION_PIXMAP(KviOption_pixmapNotifierBackground).pixmap(); - - if(pPix) - KviPixmapUtils::drawPixmapWithPainter(pPainter,pPix,KVI_OPTION_UINT(KviOption_uintNotifierPixmapAlign),e->rect(),e->rect().width(),e->rect().height()); - else pPainter->fillRect(e->rect(),KVI_OPTION_COLOR(KviOption_colorNotifierBackground)); - #ifdef COMPILE_PSEUDO_TRANSPARENCY - } - #endif - - delete pPainter; - e->ignore(); -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_notifierwindowtab.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/notifier/notifierwindowtab.h b/src/modules/notifier/notifierwindowtab.h deleted file mode 100644 index 0e6edcdbe..000000000 --- a/src/modules/notifier/notifierwindowtab.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef _KVINOTIFIERWINDOWTAB_H_ -#define _KVINOTIFIERWINDOWTAB_H_ -//============================================================================= -// -// File : notifierwindowtab.h -// Creation date : Tue 07 Jul 2009 10:28 by Fabio Bas -// -// This file is part of the KVIrc distribution -// Copyright (C) 2009 Fabio Bas < ctrlaltca at gmail dot com > -// -// This program is FREE software. You can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -/** -* \file notifierwindowtab.h -* \author Fabio Bas -* \brief Defines the tab page for the notifier object -*/ - -#include "notifiermessage.h" - -#include "kvi_settings.h" - -#include - -class QVBoxLayout; -class QWidget; -class QTabWidget; -class QPainter; -class KviWindow; - -/** -* \class KviNotifierWindowTab -* \brief Defines an object for every single tab about the tabs area -*/ -class KviNotifierWindowTab : public QScrollArea -{ - Q_OBJECT -public: - /** - * \brief Creates the tab object - * \param pWnd The name of the window represented by the tab - * \param pParent The parent area container - * \return KviNotifierWindowTab - */ - KviNotifierWindowTab(KviWindow * pWnd, QTabWidget * pParent); - - /** - * \brief Destroys the tab object - */ - ~KviNotifierWindowTab(); -private: - QString m_szLabel; - KviWindow * m_pWnd; - QTabWidget * m_pParent; - QVBoxLayout * m_pVBox; - QWidget * m_pVWidget; -public: - /** - * \brief Appends the given message to the window - * \param pMessage The message received to append - * \return void - */ - void appendMessage(KviNotifierMessage * pMessage); - - /** - * \brief Updates the GUI - * \return void - */ - void updateGui(); - - /** - * \brief Returns the name of the current window - * \return QString - */ - inline QString label() const { return m_szLabel; }; - - /** - * \brief Returns the pointer of the current window - * \return KviWindow * - */ - inline KviWindow * wnd() const { return m_pWnd; }; -protected: - virtual void mouseDoubleClickEvent(QMouseEvent * e); - virtual void resizeEvent(QResizeEvent * e); - virtual void paintEvent(QPaintEvent * e); -private slots: - /** - * \brief Emitted when the scrollbar range is changed - * \return void - */ - void scrollRangeChanged(int, int); - - /** - * \brief Emitted when the window changes its name - * \return void - */ - void labelChanged(); - - /** - * \brief Emitted when the window is being destroyed - * \return void - */ - void closeMe(); -}; - -#endif //!_KVINOTIFIERWINDOWTAB_H_ diff --git a/src/modules/objects/CMakeLists.txt b/src/modules/objects/CMakeLists.txt index 694cde24c..da456fe1b 100644 --- a/src/modules/objects/CMakeLists.txt +++ b/src/modules/objects/CMakeLists.txt @@ -8,84 +8,84 @@ IF(WIN32) ENDIF() SET(kviobjects_MOC_HDRS - class_button.h - class_checkbox.h - class_combobox.h - class_datetimeedit.h - class_dockwindow.h - class_ftp.h - class_http.h - class_lineedit.h - class_listwidget.h - class_multilineedit.h - class_painter.h - class_pixmap.h - class_popupmenu.h - class_process.h - class_radiobutton.h - class_slider.h - class_socket.h - class_spinbox.h - class_tabwidget.h - class_tablewidget.h - class_trayicon.h - class_tbrowser.h - class_toolbutton.h - class_treewidget.h - class_widget.h - class_window.h - class_wizard.h + KvsObject_button.h + KvsObject_checkBox.h + KvsObject_comboBox.h + KvsObject_dateTimeEdit.h + KvsObject_dockWindow.h + KvsObject_ftp.h + KvsObject_http.h + KvsObject_lineEdit.h + KvsObject_listWidget.h + KvsObject_multiLineEdit.h + KvsObject_painter.h + KvsObject_pixmap.h + KvsObject_popupMenu.h + KvsObject_process.h + KvsObject_radioButton.h + KvsObject_slider.h + KvsObject_socket.h + KvsObject_spinBox.h + KvsObject_tabWidget.h + KvsObject_tableWidget.h + KvsObject_trayIcon.h + KvsObject_textBrowser.h + KvsObject_toolButton.h + KvsObject_treeWidget.h + KvsObject_widget.h + KvsObject_window.h + KvsObject_wizard.h ) SET(kviobjects_SRCS libkviobjects.cpp - class_button.cpp - class_buttongroup.cpp - class_checkbox.cpp - class_combobox.cpp - class_datetimeedit.cpp - class_dialog.cpp - class_dockwindow.cpp - class_file.cpp - class_ftp.cpp - class_groupbox.cpp - class_hbox.cpp - class_http.cpp - class_label.cpp - class_layout.cpp - class_lcd.cpp - class_lineedit.cpp - class_list.cpp - class_listwidget.cpp - class_mainwindow.cpp - class_memorybuffer.cpp - class_menubar.cpp - class_multilineedit.cpp - class_painter.cpp - class_pixmap.cpp - class_popupmenu.cpp - class_process.cpp - class_progressbar.cpp - class_radiobutton.cpp - class_slider.cpp - class_socket.cpp - class_spinbox.cpp - class_sql.cpp - class_tabwidget.cpp - class_tablewidget.cpp - class_trayicon.cpp - class_tbrowser.cpp - class_toolbar.cpp - class_toolbutton.cpp - class_treewidget.cpp - class_treewidgetitem.cpp - class_vbox.cpp - class_widget.cpp - class_window.cpp - class_wizard.cpp - class_workspace.cpp - class_wrapper.cpp - class_xmlreader.cpp + KvsObject_button.cpp + KvsObject_buttonGroup.cpp + KvsObject_checkBox.cpp + KvsObject_comboBox.cpp + KvsObject_dateTimeEdit.cpp + KvsObject_dialog.cpp + KvsObject_dockWindow.cpp + KvsObject_file.cpp + KvsObject_ftp.cpp + KvsObject_groupBox.cpp + KvsObject_hBox.cpp + KvsObject_http.cpp + KvsObject_label.cpp + KvsObject_layout.cpp + KvsObject_lcd.cpp + KvsObject_lineEdit.cpp + KvsObject_list.cpp + KvsObject_listWidget.cpp + KvsObject_mainWindow.cpp + KvsObject_memoryBuffer.cpp + KvsObject_menuBar.cpp + KvsObject_multiLineEdit.cpp + KvsObject_painter.cpp + KvsObject_pixmap.cpp + KvsObject_popupMenu.cpp + KvsObject_process.cpp + KvsObject_progressBar.cpp + KvsObject_radioButton.cpp + KvsObject_slider.cpp + KvsObject_socket.cpp + KvsObject_spinBox.cpp + KvsObject_sql.cpp + KvsObject_tabWidget.cpp + KvsObject_tableWidget.cpp + KvsObject_trayIcon.cpp + KvsObject_textBrowser.cpp + KvsObject_toolBar.cpp + KvsObject_toolButton.cpp + KvsObject_treeWidget.cpp + KvsObject_treeWidgeteItem.cpp + KvsObject_vBox.cpp + KvsObject_widget.cpp + KvsObject_window.cpp + KvsObject_wizard.cpp + KvsObject_workspace.cpp + KvsObject_wrapper.cpp + KvsObject_xmlreader.cpp ) # After this call, files will be moc'ed to moc_kvi_*.cpp diff --git a/src/modules/objects/KvsObject_button.cpp b/src/modules/objects/KvsObject_button.cpp new file mode 100644 index 000000000..1730379ae --- /dev/null +++ b/src/modules/objects/KvsObject_button.cpp @@ -0,0 +1,167 @@ +//============================================================================= +// +// File : KvsObject_button.cpp +// Creation date : Wed 13 Sep 2000 02:42:05 CEST by Krzysztof Godlewski +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000 Krzysztof Godlewski +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KviError.h" +#include "KviIconManager.h" +#include "KviFile.h" + +#include "KvsObject_button.h" +#include "KvsObject_pixmap.h" + +#include +#include + +/* + @doc:button + @title: + button class + @type: + class + @short: + Button widget. + @inherits: + [class]object[/class] + [class]button[/class] + @description: + This widget provides a push button + @functions: + !fn: $setText([]) + Set the button text.[br] + See also [classfnc]$text[/classfnc](). + !fn: $text() + Return the button text.[br] + See also [classfnc]$setText[/classfnc](). + !fn: $setImage() + Sets the icon for this button. + See the [doc:image_id]image identifier[/doc] documentation for the explaination of the parameter. + !fn: $clickEvent() + Called by KVIrc when the mouse button is clicked. + The default implementation emits the [classfnc]$clicked[/classfnc]()signal. + @signals: + !sg: $clicked() + This signal is emitted by the default implementation of [classfnc]$clickEvent[/classfnc](). + @properties: + !pr: $scaledContents() + This property holds whether the label will scale its contents to fill all available space. +*/ + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_button,"button","widget") + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_button,setText) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_button,text) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_button,clickEvent) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_button,setImage) + +KVSO_END_REGISTERCLASS(KvsObject_button) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_button,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_button) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_button) + +KVSO_END_DESTRUCTOR(KvsObject_button) + +bool KvsObject_button::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + SET_OBJECT(QPushButton); + connect(widget(),SIGNAL(clicked()),this,SLOT(slotClicked())); + return true; +} + +KVSO_CLASS_FUNCTION(button,text) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setString(((QPushButton *)widget())->text()); + return true; +} + +KVSO_CLASS_FUNCTION(button,setText) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETERS_END(c) + ((QPushButton *)widget())->setText(szText); + return true; +} + +KVSO_CLASS_FUNCTION(button,setImage) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsVariant * pIcon; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("icon_or_hobject",KVS_PT_VARIANT,0,pIcon) + KVSO_PARAMETERS_END(c) + if(!pIcon) + { + c->warning(__tr2qs_ctx("Image parameter missing","object")); + return true; + } + if(pIcon->isHObject()) + { + kvs_hobject_t hObj; + pIcon->asHObject(hObj); + KviKvsObject *pObject = KviKvsKernel::instance()->objectController()->lookupObject(hObj); + if (!pObject) + { + c->warning(__tr2qs_ctx("Pixmap parameter is not an object!","objects")); + return true; + } + if(pObject->inheritsClass("pixmap")) + ((QPushButton *)widget())->setIcon(QIcon(*((KvsObject_pixmap *)pObject)->getPixmap())); + else + c->warning(__tr2qs_ctx("Object Pixmap required!","object")); + return true; + } + QString szIcon; + pIcon->asString(szIcon); + QPixmap * pix = g_pIconManager->getImage(szIcon); + if(pix) ((QPushButton *)widget())->setIcon(*pix); + else((QPushButton *)widget())->setIcon(QIcon()); + return true; +} +KVSO_CLASS_FUNCTION(button,clickEvent) +{ + emitSignal("clicked",c); + return true; +} + +// slots +void KvsObject_button::slotClicked() +{ + KviKvsVariantList *params=0; + callFunction(this,"clickEvent",params); +} + + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_button.moc" +#endif //COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/objects/KvsObject_button.h b/src/modules/objects/KvsObject_button.h new file mode 100644 index 000000000..8fb8ce8c4 --- /dev/null +++ b/src/modules/objects/KvsObject_button.h @@ -0,0 +1,53 @@ +#ifndef _CLASS_BUTTON_H_ +#define _CLASS_BUTTON_H_ +//============================================================================= +// +// File : KvsObject_button.h +// Creation date : Wed 13 Sep 2000 02:42:05 CEST by Krzysztof Godlewski +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000 Krzysztof Godlewski +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + + +#include "KvsObject_widget.h" +#include "object_macros.h" + +class KvsObject_button : public KvsObject_widget +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_button) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool setText(KviKvsObjectFunctionCall *c); + bool text(KviKvsObjectFunctionCall *c); + + bool setImage(KviKvsObjectFunctionCall *c); + bool clickEvent(KviKvsObjectFunctionCall *c); + +protected slots: + void slotClicked(); +}; + +#endif // !_CLASS_BUTTON_H_ diff --git a/src/modules/objects/KvsObject_buttonGroup.cpp b/src/modules/objects/KvsObject_buttonGroup.cpp new file mode 100644 index 000000000..82f4c1f89 --- /dev/null +++ b/src/modules/objects/KvsObject_buttonGroup.cpp @@ -0,0 +1,106 @@ +//============================================================================= +// +// File : KvsObject_buttonGroup.cpp +// Creation date : Fri Jan 28 14:21:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2009 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include "KvsObject_buttonGroup.h" +#include "KviError.h" +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KviIconManager.h" + +#include +#include + +/* + @doc: buttongroup + @keyterms: + buttongroup object class, + @title: + buttongroup class + @type: + class + @short: + Provides a buttongroup control. + @inherits: + [class]object[/class] + @description: + This object organizes buttons in a group. + @functions: + !fn: $addButton() + Adds the given button to the button group and returns an unique identifier. + !fn: $checkedButton() + Returns the button group's checked button, or 0 if no buttons are checked. +*/ + +KVSO_BEGIN_REGISTERCLASS(KvsObject_buttonGroup,"buttongroup","object") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_buttonGroup,addButton) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_buttonGroup,checkedButton) +KVSO_END_REGISTERCLASS(KvsObject_buttonGroup) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_buttonGroup,KviKvsObject) + m_iId=0; + btnDict.setAutoDelete(false); + m_pButtonGroup=new QButtonGroup(); +KVSO_END_CONSTRUCTOR(KvsObject_buttonGroup) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_buttonGroup) +btnDict.clear(); +delete m_pButtonGroup; +KVSO_END_CONSTRUCTOR(KvsObject_buttonGroup) + + +KVSO_CLASS_FUNCTION(buttonGroup,addButton) +{ + CHECK_INTERNAL_POINTER(m_pButtonGroup) + KviKvsObject * pObject; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("button",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + CHECK_HOBJECT_IS_WIDGET(pObject) + if(pObject->inheritsClass("radiobutton") || pObject->inheritsClass("checkbox")) + { + m_pButtonGroup->addButton(((QRadioButton *)(pObject->object())),m_iId); + c->returnValue()->setInteger(m_iId); + btnDict.insert(m_iId,pObject); + m_iId++; + } + else + { + c->warning(__tr2qs_ctx("Buttongroup supports only checkbox and radiobox object","objects")); + return true; + } + return true; +} +KVSO_CLASS_FUNCTION(buttonGroup,checkedButton) +{ + CHECK_INTERNAL_POINTER(m_pButtonGroup) + int id=m_pButtonGroup->checkedId(); + if (id!=-1) c->returnValue()->setHObject(btnDict.find(id)->handle()); + else c->returnValue()->setNothing(); + return true; +} diff --git a/src/modules/objects/KvsObject_buttonGroup.h b/src/modules/objects/KvsObject_buttonGroup.h new file mode 100644 index 000000000..a7d44cc91 --- /dev/null +++ b/src/modules/objects/KvsObject_buttonGroup.h @@ -0,0 +1,46 @@ +#ifndef _CLASS_BUTTONGROUP_H_ +#define _CLASS_BUTTONGROUP_H_ +//============================================================================= +// +// File : KvsObject_buttonGroup.cpp +// Creation date : Fri Jan 28 14:21:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2009 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + + +#include +#include "object_macros.h" + +class KvsObject_buttonGroup : public KviKvsObject +{ +public: + KVSO_DECLARE_OBJECT(KvsObject_buttonGroup) +protected: + QButtonGroup *m_pButtonGroup; + int m_iId; + KviPointerHashTable btnDict; + bool addButton(KviKvsObjectFunctionCall *c); + bool checkedButton(KviKvsObjectFunctionCall *c); + +}; +#endif //!_CLASS_GROUPBOX_H_ + diff --git a/src/modules/objects/KvsObject_checkBox.cpp b/src/modules/objects/KvsObject_checkBox.cpp new file mode 100644 index 000000000..53f11fda7 --- /dev/null +++ b/src/modules/objects/KvsObject_checkBox.cpp @@ -0,0 +1,136 @@ +//============================================================================= +// +// File : KvsObject_checkBox.cpp +// Creation date : Wed 13 Sep 2000 02:42:05 CEST by Krzysztof Godlewski +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000 Krzysztof Godlewski +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include "KviError.h" +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KvsObject_checkBox.h" + +#include + +/* + @doc: checkbox + @title: + checkbox class + @type: + class + @short: + Check box with a text description + @inherits: + [class]object[/class] + [class]button[/class] + @description: + This widget provides a check box - it is a kind of a toggle + button. It can have two states: on (checked) and off + (unchecked). + @functions: + !fn: $isChecked() + Returns '1' if the check box is checked, '0' otherwise.[br] + See also [classfnc]$setChecked[/classfnc](). + !fn: $setChecked([]) + Sets the check box 'checked state' to . + See also [classfnc]$isChecked[/classfnc](). + !fn: $setText([]) + Sets the label text associated with the checkbox to .[br] + !fn: $toggleEvent() + Called by KVIrc when the checkbox state is toggled. + The default implementation emits the toggled() signal. +*/ + +//--------------------------------------------------------------------------------- + +KVSO_BEGIN_REGISTERCLASS(KvsObject_checkBox,"checkbox","button") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_checkBox,setChecked) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_checkBox,isChecked) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_checkBox,toggleEvent) +KVSO_END_REGISTERCLASS(KvsObject_checkBox) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_checkBox,KvsObject_button) + +KVSO_END_CONSTRUCTOR(KvsObject_checkBox) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_checkBox) + +KVSO_END_CONSTRUCTOR(KvsObject_checkBox) + +bool KvsObject_checkBox::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + QCheckBox * cb = new QCheckBox(parentScriptWidget()); + cb->setObjectName(getName().toUtf8().data()); + setObject(cb, true); + connect(cb,SIGNAL(toggled(bool)),this,SLOT(toggled(bool))); + connect(widget(),SIGNAL(clicked()),this,SLOT(slotClicked())); + return true; +} + +KVSO_CLASS_FUNCTION(checkBox,isChecked) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setBoolean(((QCheckBox *)widget())->isChecked()); + return true; +} + +KVSO_CLASS_FUNCTION(checkBox,setChecked) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bChecked; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bChecked",KVS_PT_BOOL,KVS_PF_OPTIONAL,bChecked) + KVSO_PARAMETERS_END(c) + ((QCheckBox *)widget())->setChecked(bChecked); + return true; +} + +KVSO_CLASS_FUNCTION(checkBox,setText) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("",KVS_PT_STRING,0,szText) + KVSO_PARAMETERS_END(c) + ((QCheckBox *)widget())->setText(szText); + return true; +} + +KVSO_CLASS_FUNCTION(checkBox,toggleEvent) +{ + emitSignal("toggled",c,c->params()); + return true; +} + +//slots +void KvsObject_checkBox::toggled(bool b) +{ + KviKvsVariantList params(new KviKvsVariant(b)); + callFunction(this,"toggleEvent",¶ms); +} + + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_checkBox.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES + diff --git a/src/modules/objects/KvsObject_checkBox.h b/src/modules/objects/KvsObject_checkBox.h new file mode 100644 index 000000000..a1cc15087 --- /dev/null +++ b/src/modules/objects/KvsObject_checkBox.h @@ -0,0 +1,50 @@ +#ifndef _CLASS_CHECKBOX_H_ +#define _CLASS_CHECKBOX_H_ + +//============================================================================= +// +// File : KvsObject_checkBox.h +// Creation date : Wed 13 Sep 2000 02:42:05 CEST by Krzysztof Godlewski +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000 Krzysztof Godlewski +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + + +#include "KvsObject_button.h" +#include "object_macros.h" + +class KvsObject_checkBox : public KvsObject_button +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_checkBox) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + bool setChecked(KviKvsObjectFunctionCall *c); + bool isChecked(KviKvsObjectFunctionCall *c); + bool toggleEvent(KviKvsObjectFunctionCall *c); + bool setText(KviKvsObjectFunctionCall *c); +protected slots: + void toggled(bool b); +}; +#endif // !_CLASS_CHECKBOX_H_ diff --git a/src/modules/objects/KvsObject_comboBox.cpp b/src/modules/objects/KvsObject_comboBox.cpp new file mode 100644 index 000000000..83dfc51ab --- /dev/null +++ b/src/modules/objects/KvsObject_comboBox.cpp @@ -0,0 +1,366 @@ +//============================================================================= +// +// File : KvsObject_comboBox.cpp +// Creation date : Wed 13 Sep 2000 02:42:05 CEST by Krzysztof Godlewski +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000 Krzysztof Godlewski +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include "KviError.h" +#include "KviLocale.h" +#include "kvi_debug.h" +#include "KvsObject_list.h" +#include "KvsObject_comboBox.h" + +#include +#include +#include + +/* + @doc: combobox + @keyterms: + combobox object class, selection + @title: + combobox class + @type: + class + @short: + Combined button and popup list + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + @functions: + !fn: $insertItem(, ) + Inserts a text item at position . If index is negative or + not specified the item is appended. + !fn: $changeItem(, ) + Changes text of item at to . + !fn: $removeItem() + Removes item at given index. + !fn: $setMaxCount() + Sets the maximum number of items the combo box can hold to + . If is smaller than the current number of items, + the list is truncated at the end. There is no limit by default. + !fn: $maxCount() + Returns the current maximum number of items in the combo box. + !fn: $count() + Returns number of items in the widget. + !fn: $current() + Returns currently selected item. + !fn: $currentItem() + Returns index of currently selected item. + !fn: $setEditable() + Make the input field editable, if . Otherwise the + user may only choose one of the items in the combo box.[br] + If the parameter is ommited, it is assumed to be false. + !fn: $editable() + Returns whether the combobox is editable or not. + !fn: $setEditText(,[]) + Sets the text in the embedded line edit to newText without + changing the combo's contents. Does nothing if the combo + isn't editable. If the optional quiet parameter is true no warning will be print if text will be empty. + !fn: $clear() + Removes all the items from the combo box + !fn: $textAt() + Returns item at given index. + !fn: $setCurrentItem() + Sets the current combobox item. This is the item to be displayed on the combobox button. + !fn: $activatedEvent() + This function is called by the framework when a new item has activated. The index value is the position of the new item.[br] + The default implementation emits the [classfnc]$activated[/classfnc]() signal, + !fn: $textChangedEvent() + This function is called when the text in an editable combobox has changed.[br] + The function return the new text in its argument.[br] + The default implementation emits the [classfnc]$textChanged[/classfnc]() signal. + @signals: + !sg: $textChanged() + This signal is emitted by the default implementation of [classfnc]$textChangedEvent[/classfnc](). + !sg: $activated() + This signal is emitted by the default implementation of [classfnc]$activatedEvent[/classfnc](). + +*/ +KVSO_BEGIN_REGISTERCLASS(KvsObject_comboBox,"combobox","widget") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,insertItem) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,changeItem) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,removeItem) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,clear) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,setMaxCount) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,maxCount) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,count) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,current) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,currentItem) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,setEditable); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,editable) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,setEditText) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,textAt) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,textLineEdit) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,setTextLineEdit) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,setCurrentItem) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,popup) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,setInsertionPolicy) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,textChangedEvent) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_comboBox,activatedEvent) + +KVSO_END_REGISTERCLASS(KvsObject_comboBox) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_comboBox,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_comboBox) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_comboBox) + +KVSO_END_CONSTRUCTOR(KvsObject_comboBox) + +bool KvsObject_comboBox::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + SET_OBJECT(QComboBox); + connect (((QComboBox *)widget()),SIGNAL(activated( int )),this,SLOT(slotActivated( int ))); + connect (((QComboBox *)widget()),SIGNAL(editTextChanged(const QString & )),this,SLOT(editTextChanged(const QString & ))); + return true; +} + +KVSO_CLASS_FUNCTION(comboBox,insertItem) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iIndex; + QString szItem; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("item",KVS_PT_STRING,0,szItem) + KVSO_PARAMETER("index",KVS_PT_INT,KVS_PF_OPTIONAL,iIndex) + KVSO_PARAMETERS_END(c) + if(c->paramCount()==1) + ((QComboBox *)widget())->addItem(szItem); + else + ((QComboBox *)widget())->insertItem( iIndex,szItem); + return true; +} +KVSO_CLASS_FUNCTION(comboBox,clear) +{ + CHECK_INTERNAL_POINTER(widget()) + ((QComboBox *)widget())->clear(); + return true; +} +KVSO_CLASS_FUNCTION(comboBox,changeItem) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uIndex,cnt; + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex) + KVSO_PARAMETERS_END(c) + if (szText.isEmpty()) c->warning(__tr2qs_ctx("No string parameter given - using empty string","objects")); + if(uIndex >= (cnt = ((QComboBox *)widget())->count())) + { + c->warning(__tr2qs_ctx("Item index [%d] is too big - defaulting to " \ + "$count() - 1 [%d]","objects"), uIndex, cnt); + uIndex = cnt - 1; + } + ((QComboBox *)widget())->setItemText( uIndex,szText); + return true; + +} +KVSO_CLASS_FUNCTION(comboBox,removeItem) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uIndex,cnt; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex) + KVSO_PARAMETERS_END(c) + if(uIndex >= (cnt = ((QComboBox *)widget())->count())) + { + c->warning(__tr2qs_ctx("Item index [%d] is too big - defaulting to " \ + "$count() - 1 [%d]","objects"), uIndex, cnt); + uIndex = cnt - 1; + } + + ((QComboBox *)widget())->removeItem(uIndex); + + return true; + +} +KVSO_CLASS_FUNCTION(comboBox,setMaxCount) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t iMax; + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("count",KVS_PT_UNSIGNEDINTEGER,0,iMax) + KVSO_PARAMETERS_END(c) + ((QComboBox *)widget())->setMaxCount(iMax); + return true; +} +KVSO_CLASS_FUNCTION(comboBox,maxCount) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QComboBox *)widget())->maxCount()); + return true; +} +KVSO_CLASS_FUNCTION(comboBox,count) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QComboBox *)widget())->count()); + return true; +} +KVSO_CLASS_FUNCTION(comboBox,current) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setString(((QComboBox *)widget())->currentText()); + return true; +} +KVSO_CLASS_FUNCTION(comboBox,currentItem) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QComboBox *)widget())->currentIndex()); + return true; +} +KVSO_CLASS_FUNCTION(comboBox,textLineEdit) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setString(((QComboBox *)widget())->lineEdit()->text()); + return true; +} + +KVSO_CLASS_FUNCTION(comboBox,setEditable) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bFlag; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bflag",KVS_PT_BOOLEAN,0,bFlag) + KVSO_PARAMETERS_END(c) + ((QComboBox *)widget())->setEditable(bFlag); + return true; +} +KVSO_CLASS_FUNCTION(comboBox,setTextLineEdit) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETERS_END(c) + ((QComboBox *)widget())->lineEdit()->setText(szText); + return true; +} + +KVSO_CLASS_FUNCTION(comboBox,editable) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setBoolean(((QComboBox *)widget())->isEditable()); + return true; +} +KVSO_CLASS_FUNCTION(comboBox,setEditText) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szText; + bool bQuiet=false; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETER("quiet",KVS_PT_BOOLEAN,KVS_PF_OPTIONAL,bQuiet) + KVSO_PARAMETERS_END(c) + if (szText.isEmpty() && !bQuiet) c->warning(__tr2qs_ctx("No string parameter given - using empty string","objects")); + ((QComboBox *)widget())->setEditText(szText); + return true; +} +KVSO_CLASS_FUNCTION(comboBox,textAt) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uIndex; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex) + KVSO_PARAMETERS_END(c) + c->returnValue()->setString(((QComboBox *)widget())->itemText(uIndex)); + return true; +} +KVSO_CLASS_FUNCTION(comboBox,setCurrentItem) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uIndex; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex) + KVSO_PARAMETERS_END(c) + ((QComboBox *)widget())->setCurrentIndex(uIndex); + return true; +} +KVSO_CLASS_FUNCTION(comboBox,popup) +{ + Q_UNUSED(c); + + if(widget()) + ((QComboBox *)widget())->showPopup(); + return true; +} +KVSO_CLASS_FUNCTION(comboBox,setInsertionPolicy) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szPolicy; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("policy",KVS_PT_STRING,0,szPolicy) + KVSO_PARAMETERS_END(c) + if(KviQString::equalCI(szPolicy,"NoInsertion")) + ((QComboBox *)widget())->setInsertPolicy(QComboBox::NoInsert); + else if(KviQString::equalCI(szPolicy,"AtTop")) + ((QComboBox *)widget())->setInsertPolicy(QComboBox::InsertAtTop); + else if(KviQString::equalCI(szPolicy,"AtBotton")) + ((QComboBox *)widget())->setInsertPolicy(QComboBox::InsertAtBottom); + else if(KviQString::equalCI(szPolicy,"AtCurrent")) + ((QComboBox *)widget())->setInsertPolicy(QComboBox::InsertAtCurrent); + else if(KviQString::equalCI(szPolicy,"AfterCurrent")) + ((QComboBox *)widget())->setInsertPolicy(QComboBox::InsertAfterCurrent); + else if(KviQString::equalCI(szPolicy,"BeforeCurrent")) + ((QComboBox *)widget())->setInsertPolicy(QComboBox::InsertBeforeCurrent); + else c->warning(__tr2qs_ctx("Invalid insertion Policy '%Q'","objects"),&szPolicy); + return true; +} + +KVSO_CLASS_FUNCTION(comboBox,textChangedEvent) +{ + emitSignal("textChanged",c,c->params()); + return true; +} + + + +KVSO_CLASS_FUNCTION(comboBox,activatedEvent) +{ + emitSignal("activated",c,c->params()); + return true; +} + +//slots +void KvsObject_comboBox::editTextChanged(const QString &text) +{ + KviKvsVariantList params(new KviKvsVariant(text)); + callFunction(this,"textChangedEvent",¶ms); +} + +void KvsObject_comboBox::slotActivated(int i) +{ + KviKvsVariantList params(new KviKvsVariant((kvs_int_t)i)); + callFunction(this,"activatedEvent",¶ms); +} + + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_comboBox.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES + diff --git a/src/modules/objects/KvsObject_comboBox.h b/src/modules/objects/KvsObject_comboBox.h new file mode 100644 index 000000000..a10ac6c29 --- /dev/null +++ b/src/modules/objects/KvsObject_comboBox.h @@ -0,0 +1,74 @@ +#ifndef _CLASS_COMBOBOX_H_ +#define _CLASS_COMBOBOX_H_ + +//============================================================================= +// +// File : KvsObject_comboBox.h +// Creation date : Wed 13 Sep 2000 02:42:05 CEST by Krzysztof Godlewski +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000 Krzysztof Godlewski +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include +#include "KvsObject_widget.h" +#include "object_macros.h" + +class KvsObject_comboBox : public KvsObject_widget +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_comboBox) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool insertItem(KviKvsObjectFunctionCall *c); + bool changeItem(KviKvsObjectFunctionCall *c); + bool removeItem(KviKvsObjectFunctionCall *c); + bool clear(KviKvsObjectFunctionCall *c); +//#warning "$insertPixItem" +//#warning "$changePixItem" + + bool count(KviKvsObjectFunctionCall *c); + bool setMaxCount(KviKvsObjectFunctionCall *c); + bool maxCount(KviKvsObjectFunctionCall *c); + bool current(KviKvsObjectFunctionCall *c); + bool currentItem(KviKvsObjectFunctionCall *c); + bool setEditable(KviKvsObjectFunctionCall *c); + bool editable(KviKvsObjectFunctionCall *c); + bool setEditText(KviKvsObjectFunctionCall *c); + bool textAt(KviKvsObjectFunctionCall *c); + bool textLineEdit(KviKvsObjectFunctionCall *c); + bool setTextLineEdit(KviKvsObjectFunctionCall *c); + + bool setInsertionPolicy(KviKvsObjectFunctionCall *c); + + bool setCurrentItem(KviKvsObjectFunctionCall *c); + bool popup(KviKvsObjectFunctionCall *c); + bool textChangedEvent(KviKvsObjectFunctionCall *c); + bool activatedEvent(KviKvsObjectFunctionCall *c); +protected slots: + void editTextChanged(const QString &); + void slotActivated(int); +}; + +#endif // !_CLASS_COMBOBOX_H_ diff --git a/src/modules/objects/KvsObject_dateTimeEdit.cpp b/src/modules/objects/KvsObject_dateTimeEdit.cpp new file mode 100644 index 000000000..e992d69d7 --- /dev/null +++ b/src/modules/objects/KvsObject_dateTimeEdit.cpp @@ -0,0 +1,162 @@ +//============================================================================= +// +// File : KvsObject_dateTimeEdit.cpp +// Creation date : Wed 30 Gen 2009 09:30:05 CEST by Carbone Alessandro +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2009 Carbone Alessandro (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KviError.h" +#include "KviIconManager.h" +#include "KviFile.h" + +#include "KvsObject_dateTimeEdit.h" +#include "KvsObject_pixmap.h" + + #include + +/* + @doc:datetimeedit + @title: + datetimeedit class + @type: + class + @short: + Datetimeedit widget. + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + This widget provides a datetimeedit. + @functions: + !fn: $setDate(,) + Sets the date of the widget using the format . Possible values for format are: + d the day as number without a leading zero (1 to 31) + dd the day as number with a leading zero (01 to 31) + ddd the abbreviated localized day name (e.g. 'Mon' to 'Sun'). Uses QDate::shortDayName(). + dddd the long localized day name (e.g. 'Monday' to 'Qt::Sunday'). Uses QDate::longDayName(). + M the month as number without a leading zero (1-12) + MM the month as number with a leading zero (01-12) + MMM the abbreviated localized month name (e.g. 'Jan' to 'Dec'). Uses QDate::shortMonthName(). + MMMM the long localized month name (e.g. 'January' to 'December'). Uses QDate::longMonthName(). + yy the year as two digit number (00-99) + yyyy the year as four digit number + !fn: $date() + Returns the widget date according to format. + !fn: $setTime(,) + Sets the date of the widget using the format . Possibile values for format are: + h the hour without a leading zero + hh the hour with a leading zero + m the minute without a leading zero + mm the minute with a leading zero + s the second without a leading zero + ss the second with a leading zero + z the milliseconds without leading zeroes + zzz the milliseconds with leading zeroes + AP(or ap) use AM/PM display. AP will be replaced by either "AM" or "PM". + !fn: $time() + Returns the widget time according to format. +*/ + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_dateTimeEdit,"datetimeedit","widget") + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_dateTimeEdit,date) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_dateTimeEdit,setDate) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_dateTimeEdit,setTime) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_dateTimeEdit,time) + +KVSO_END_REGISTERCLASS(KvsObject_dateTimeEdit) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_dateTimeEdit,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_dateTimeEdit) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_dateTimeEdit) + +KVSO_END_DESTRUCTOR(KvsObject_dateTimeEdit) + +bool KvsObject_dateTimeEdit::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + QDateTimeEdit *obj=new QDateTimeEdit(QDate::currentDate(),parentScriptWidget()); + obj->setObjectName(getName()); + setObject(obj,true); + return true; +} + +KVSO_CLASS_FUNCTION(dateTimeEdit,date) +{ + + CHECK_INTERNAL_POINTER(widget()) + QString szFormat; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("format",KVS_PT_STRING,0,szFormat) + KVSO_PARAMETERS_END(c) + + c->returnValue()->setString(((QDateTimeEdit *)widget())->date().toString(szFormat)); + + return true; +} +KVSO_CLASS_FUNCTION(dateTimeEdit,setDate) +{ + + CHECK_INTERNAL_POINTER(widget()) + QString szFormat,szDate; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("format",KVS_PT_STRING,0,szFormat) + KVSO_PARAMETER("date",KVS_PT_STRING,0,szDate) + KVSO_PARAMETERS_END(c) + QDate date; + date=date.fromString(szDate,szFormat); + ((QDateTimeEdit *)widget())->setDate(date); + return true; +} +KVSO_CLASS_FUNCTION(dateTimeEdit,time) +{ + + CHECK_INTERNAL_POINTER(widget()) + QString szFormat; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("format",KVS_PT_STRING,0,szFormat) + KVSO_PARAMETERS_END(c) + + c->returnValue()->setString(((QDateTimeEdit *)widget())->time().toString(szFormat)); + + return true; +} +KVSO_CLASS_FUNCTION(dateTimeEdit,setTime) +{ + + CHECK_INTERNAL_POINTER(widget()) + QString szFormat,szTime; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("format",KVS_PT_STRING,0,szFormat) + KVSO_PARAMETER("date",KVS_PT_STRING,0,szTime) + KVSO_PARAMETERS_END(c) + QTime time; + time=time.fromString(szTime,szFormat); + ((QDateTimeEdit *)widget())->setTime(time); + return true; +} +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_dateTimeEdit.moc" +#endif //COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/objects/KvsObject_dateTimeEdit.h b/src/modules/objects/KvsObject_dateTimeEdit.h new file mode 100644 index 000000000..fc2963a8f --- /dev/null +++ b/src/modules/objects/KvsObject_dateTimeEdit.h @@ -0,0 +1,56 @@ +#ifndef _CLASS_datetimeedit_H_ +#define _CLASS_datetimeedit_H_ +//============================================================================= +// +// File : KvsObject_dateTimeEdit.h +// Creation date : Wed 30 Gen 2009 09:30:05 CEST by Carbone Alessandro +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2009 Carbone Alessandro (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + + +#include "KvsObject_widget.h" +#include "object_macros.h" + +class KvsObject_dateTimeEdit : public KvsObject_widget +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_dateTimeEdit) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool date(KviKvsObjectFunctionCall *c); + bool setDate(KviKvsObjectFunctionCall *c); + bool time(KviKvsObjectFunctionCall *c); + bool setTime(KviKvsObjectFunctionCall *c); + + /* bool text(KviKvsObjectFunctionCall *c); + + bool setImage(KviKvsObjectFunctionCall *c); + bool clickEvent(KviKvsObjectFunctionCall *c); +*/ +protected slots: + //void slotClicked(); +}; + +#endif // !_CLASS_datetimeedit_H_ diff --git a/src/modules/objects/KvsObject_dialog.cpp b/src/modules/objects/KvsObject_dialog.cpp new file mode 100644 index 000000000..85835cac0 --- /dev/null +++ b/src/modules/objects/KvsObject_dialog.cpp @@ -0,0 +1,91 @@ +//============================================================================= +// +// File : KvsObject_dialog.cpp +// Creation date : Sun Apr 10 22:51:48 CEST 2002 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_dialog.h" +#include "KviError.h" +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KviMainWindow.h" +#include "KviApplication.h" + +#include + + +/* + @doc: dialog + @title: + dialog class + @type: + class + @short: + A toplevel dialog object + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + Rappresents a dialog object. The class is really + similar to the widget class, it has only a couple of minor differences. + A dialog is always a top-level widget, but if it has a parent, its default + location is centered on top of the parent. It will also share the parent's windowlist entry. + !fn; setModal () + If you call $setModal(1) then the dialog will have non-blocking modal behaviour: + it will appear above its parent widget and block its input until it's closed. + @functions: +*/ + +KVSO_BEGIN_REGISTERCLASS(KvsObject_dialog,"dialog","widget") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_dialog,setModal) +KVSO_END_REGISTERCLASS(KvsObject_dialog) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_dialog,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_dialog) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_dialog) + +KVSO_END_CONSTRUCTOR(KvsObject_dialog) + +bool KvsObject_dialog::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + QWidget * w = g_pApp->activeModalWidget(); + if(!w)w = g_pFrame; + QDialog * d = new QDialog(parentScriptWidget() ? parentScriptWidget() : w); + d->setObjectName(getName()); + //d->setModal(true); + setObject(d); + return true; +} +KVSO_CLASS_FUNCTION(dialog,setModal) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + ((QDialog *)widget())->setModal(bEnabled); + return true; +} + + diff --git a/src/modules/objects/KvsObject_dialog.h b/src/modules/objects/KvsObject_dialog.h new file mode 100644 index 000000000..602de8756 --- /dev/null +++ b/src/modules/objects/KvsObject_dialog.h @@ -0,0 +1,43 @@ +#ifndef _CLASS_DIALOG_H_ +#define _CLASS_DIALOG_H_ +//============================================================================= +// +// File : KvsObject_dialog.h +// Creation date : Sun Apr 10 22:51:48 CEST 2002 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_widget.h" +#include "object_macros.h" + +class KvsObject_dialog : public KvsObject_widget +{ + +public: + KVSO_DECLARE_OBJECT(KvsObject_dialog) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + bool setModal(KviKvsObjectFunctionCall *c); +}; + +#endif // !_CLASS_DIALOG_H_ + diff --git a/src/modules/objects/KvsObject_dockWindow.cpp b/src/modules/objects/KvsObject_dockWindow.cpp new file mode 100644 index 000000000..8a9eb15a7 --- /dev/null +++ b/src/modules/objects/KvsObject_dockWindow.cpp @@ -0,0 +1,181 @@ +//============================================================================= +// +// File : KvsObject_dockWindow.cpp +// Creation date : Thu 29 Dec 2005 23:45:11 by Szymon Stefanek +// +// This file is part of the KVIrc IRC Client distribution +// Copyright (C) 2005-2010 Szymon Stefanek +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_dockWindow.h" + +#include "KviMainWindow.h" +#include "KviLocale.h" +#include "KviQString.h" + +#include +#define QT_DOCK_WINDOW QDockWidget +#include + +/* + @doc: dockwindow + @title: + dockwindow class + @type: + class + @short: + A window dockable to the KVIrc main frame + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + A window dockable to the KVIrc main frame borders (like a toolbar). + @functions: + !fn: $addWidget() + Adds to the internal layout of this dock window.[br] + The widget must be a child of this dock window (otherwise strange things may happen). + !fn: $setAllowedDockAreas() + Sets the allowed main window dock areas for this dock window.[br] + must be a combination of "l","r","t","b","f" and "m".[br] + "l" stands for left dock area, "r" stands for right dock area, "t" stands for the top dock areas, "b" stands for the bottom dock area, "f" stands for "floating" and "m" for "minimized".[br] + If a flag is present then the related block area is enabled,otherwise it is disabled. + !fn: $dock() + Docks this dock window to the specified dockarea of the main KVIrc window which can be one of "l" (left dock area), "t" (top dock area), "r" (right dock area), "b" (bottom dock area), "f" (floating) and "m" (minimized). +*/ + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_dockWindow,"dockwindow","widget") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_dockWindow,addWidget) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_dockWindow,setAllowedDockAreas) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_dockWindow,dock) +KVSO_END_REGISTERCLASS(KvsObject_dockWindow) + + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_dockWindow,KvsObject_widget) +KVSO_END_CONSTRUCTOR(KvsObject_dockWindow) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_dockWindow) +KVSO_END_DESTRUCTOR(KvsObject_dockWindow) + +#define _pDockWindow ((QDockWidget *)widget()) + +bool KvsObject_dockWindow::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + QDockWidget * pWidget = new QDockWidget(g_pFrame); + pWidget->setObjectName(getName()); + setObject(pWidget); + return true; +} + +KVSO_CLASS_FUNCTION(dockWindow,addWidget) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_hobject_t hWidget; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hWidget) + KVSO_PARAMETERS_END(c) + if(hWidget == (kvs_hobject_t)0) + { + // null widget ? + c->warning(__tr2qs_ctx("Can't add a null object","objects")); + return true; + } + + KviKvsObject * pWidget = KviKvsKernel::instance()->objectController()->lookupObject(hWidget); + if(!pWidget) + { + c->warning(__tr2qs_ctx("Invalid object handle passed as parameter (the object is no longer existing ?)","objects")); + return true; + } + + if(!pWidget->object()) + { + c->warning(__tr2qs_ctx("Object in invalid state","objects")); + return true; + } + + if(!pWidget->object()->isWidgetType()) + { + c->warning(__tr2qs_ctx("Can't set a non-widget object to be the main widget of a dock window","objects")); + return true; + } + + if(((QWidget *)(pWidget->object()))->parent() != (QObject *)_pDockWindow) + { + c->warning(__tr2qs_ctx("The added widget is not a child of this dock window","objects")); + } + + _pDockWindow->setWidget((QWidget *)(pWidget->object())); + return true; +} + + +KVSO_CLASS_FUNCTION(dockWindow,setAllowedDockAreas) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szFlags; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("docks",KVS_PT_STRING,0,szFlags) + KVSO_PARAMETERS_END(c) + Qt::DockWidgetAreas fAreas = Qt::NoDockWidgetArea; + if(szFlags.indexOf('t',Qt::CaseInsensitive) >= 0) + fAreas |= Qt::TopDockWidgetArea; + if(szFlags.indexOf('l',Qt::CaseInsensitive) >= 0) + fAreas |= Qt::LeftDockWidgetArea; + if(szFlags.indexOf('r',Qt::CaseInsensitive) >= 0) + fAreas |= Qt::RightDockWidgetArea; + if(szFlags.indexOf('b',Qt::CaseInsensitive) >= 0) + fAreas |= Qt::BottomDockWidgetArea; + _pDockWindow->setAllowedAreas(fAreas); + QDockWidget::DockWidgetFeatures fFeatures = _pDockWindow->features(); + if(szFlags.indexOf('f',Qt::CaseInsensitive)) + fFeatures |= QDockWidget::DockWidgetFloatable; + else + fFeatures &= ~QDockWidget::DockWidgetFloatable; + // no support for minimized dock widgets + _pDockWindow->setFeatures(fFeatures); + + + return true; +} + + +KVSO_CLASS_FUNCTION(dockWindow,dock) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szDock; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("dock",KVS_PT_STRING,0,szDock) + KVSO_PARAMETERS_END(c) + g_pFrame->removeDockWidget(_pDockWindow); + if(szDock.indexOf('m',Qt::CaseInsensitive) == -1)_pDockWindow->setFloating(false); + if(szDock.indexOf('t',Qt::CaseInsensitive) != -1)g_pFrame->addDockWidget(Qt::TopDockWidgetArea,_pDockWindow); + else if(szDock.indexOf('l',Qt::CaseInsensitive) != -1)g_pFrame->addDockWidget(Qt::LeftDockWidgetArea,_pDockWindow); + else if(szDock.indexOf('r',Qt::CaseInsensitive) != -1)g_pFrame->addDockWidget(Qt::RightDockWidgetArea,_pDockWindow); + else if(szDock.indexOf('b',Qt::CaseInsensitive) != -1)g_pFrame->addDockWidget(Qt::BottomDockWidgetArea,_pDockWindow); + else if(szDock.indexOf('f',Qt::CaseInsensitive) != -1)_pDockWindow->setFloating(true); + else if(szDock.indexOf('m',Qt::CaseInsensitive) != -1)qDebug("Sorry: no support for minimized dock widgets in Qt4"); + else c->warning(__tr2qs_ctx("Invalid dock area specified","objects")); + return true; +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_dockWindow.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES + diff --git a/src/modules/objects/KvsObject_dockWindow.h b/src/modules/objects/KvsObject_dockWindow.h new file mode 100644 index 000000000..df6a4a6e1 --- /dev/null +++ b/src/modules/objects/KvsObject_dockWindow.h @@ -0,0 +1,44 @@ +#ifndef _CLASS_DOCKWINDOW_H_ +#define _CLASS_DOCKWINDOW_H_ +//============================================================================= +// +// File : KvsObject_dockWindow.h +// Creation date : Thu 29 Dec 2005 23:45:11 by Szymon Stefanek +// +// This file is part of the KVIrc IRC Client distribution +// Copyright (C) 2005-2010 Szymon Stefanek +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" +#include "object_macros.h" +#include "KvsObject_widget.h" + +class KvsObject_dockWindow : public KvsObject_widget +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_dockWindow) +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool addWidget(KviKvsObjectFunctionCall *c); + bool setAllowedDockAreas(KviKvsObjectFunctionCall * c); + bool dock(KviKvsObjectFunctionCall * c); +}; + +#endif //!_CLASS_DOCKWINDOW_H_ diff --git a/src/modules/objects/KvsObject_file.cpp b/src/modules/objects/KvsObject_file.cpp new file mode 100644 index 000000000..909b1c552 --- /dev/null +++ b/src/modules/objects/KvsObject_file.cpp @@ -0,0 +1,648 @@ +//============================================================================= +// +// File : KvsObject_file.cpp +// Creation date : Fri Mar 18 21:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include "KvsObject_file.h" +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KviError.h" +#include "KviFile.h" +#include "KviFileUtils.h" +#include "KvsObject_memoryBuffer.h" + +#include +//#include +#include + +#define CHECK_FILE_IS_OPEN if (!m_pFile->isOpen())\ + {c->warning(__tr2qs_ctx("File is not open!","objects"));return true;} + +// needed for $open() + +const char * const mod_tbl[] = { + "Raw", + "ReadOnly", + "WriteOnly", + "ReadWrite", + "Append", + "Truncate" +}; + +const QIODevice::OpenMode mod_cod[] = { + QIODevice::Unbuffered, + QIODevice::ReadOnly, + QIODevice::WriteOnly, + QIODevice::ReadWrite, + QIODevice::Append, + QIODevice::Truncate +}; + +#define mod_num (sizeof(mod_tbl) / sizeof(mod_tbl[0])) + +/* + @doc: file + @keyterms: + file object class, creating files + @title: + file class + @type: + class + @short: + I/O device that operates on files + @inherits: + [class]object[/class] + @description: + This object class provides access to files - basic I/O + operations, copying, removing etc... + @functions: + !fn: $setName() + Sets the file name to . It does [b]not move[/b] the file, + it just changes the file the object is "pointing to". You can + not change names of already open files.[br] + See also: [classfnc]$open[/classfnc](), + [classfnc]$name[/classfnc](). + !fn: $name() + Returns name set by [classfnc]$setName[/classfnc]().[br] + See also: [classfnc]$setName[/classfnc](). + !fn: $open(, ) + Attempts to open the file in specified mode or modes "sum". + Valid modes are:[br] + [pre] + Raw - raw, non-buffered access[br] + ReadOnly - opens the file read-only[br] + WriteOnly - opens the file write-only[br] + ReadWrite - opens the file in read-write mode[br] + Append - opens the file in append mode. The file index is set to the end of the file.[br] + Truncate - truncates the file[br] + [/pre] + If you call this function without any parameters, the file is + opened in ReadOnly mode.[br] + When working with buffered files, data is not written directly + to the file at once. You must call [classfnc]$flush[/classfnc]() to force it.[br] + See also: [classfnc]$close[/classfnc](), + [classfnc]$flush[/classfnc](). + !fn: $isOpen() + Returns '1' if the file is open, '0' otherwise. + !fn: $close() + Closes the file, flushing the buffers first.[br] + See also: [classfnc]$flush[/classfnc](). + !fn: $flush() + Flushes the file buffer to disk. Calling this after opening the + file in 'Raw' mode doesn't make much sense.[br] + See also: [classfnc]$open[/classfnc](), + [classfnc]$close[/classfnc](). + !fn: $size() + Returns current file size. + !fn: $atEnd() + Returns '1' if you have reached end of the file, '0' otherwise. + [br]See also: [classfnc]$seek[/classfnc](), + [classfnc]$where[/classfnc](). + !fn: $where() + Returns current position in the file (file index).[br] + See also: [classfnc]$seek[/classfnc](). + !fn: $seek() + Sets the file index to .[br] + See also: [classfnc]$where[/classfnc](), + [classfnc]$atEnd[/classfnc](). + !fn: $putch() + Writes character to the file and increments file + index.[br] + See also: [classfnc]$getch[/classfnc](), + [classfnc]$ungetch[/classfnc](). + !fn: $getch() + Reads a character from the file and increments file index.[br] + See also: [classfnc]$putch[/classfnc](), + [classfnc]$ungetch[/classfnc](). + !fn: $ungetch() + Puts the character back to the file and + decrements the file index. This is usually called to undo a + $getch() call.[br] + See also: [classfnc]$getch[/classfnc], + [classfnc]$putch[/classfnc](). + !fn: $readLine() + Reads a line of text from the file and increments file index. + !fn: $writeLine() + Appends a line of text to the end of the file. + $readBlock() + $writeBlock() +*/ + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_file,"file","object") + KVSO_REGISTER_HANDLER(KvsObject_file,"setName",setName) + KVSO_REGISTER_HANDLER(KvsObject_file,"name",name) + + KVSO_REGISTER_HANDLER(KvsObject_file,"open",open) + KVSO_REGISTER_HANDLER(KvsObject_file,"isOpen",isOpen) + KVSO_REGISTER_HANDLER(KvsObject_file,"close",close) + KVSO_REGISTER_HANDLER(KvsObject_file,"flush",flush) + + KVSO_REGISTER_HANDLER(KvsObject_file,"size",size) + KVSO_REGISTER_HANDLER(KvsObject_file,"resize",resize) + + KVSO_REGISTER_HANDLER(KvsObject_file,"atEnd",atEnd) + KVSO_REGISTER_HANDLER(KvsObject_file,"where",where) + KVSO_REGISTER_HANDLER(KvsObject_file,"seek",seek) + + KVSO_REGISTER_HANDLER(KvsObject_file,"putch",putch) + KVSO_REGISTER_HANDLER(KvsObject_file,"getch",getch) + KVSO_REGISTER_HANDLER(KvsObject_file,"ungetch",unGetch) + KVSO_REGISTER_HANDLER(KvsObject_file,"readByte",readByte) + + KVSO_REGISTER_HANDLER(KvsObject_file,"readBlock",readBlock) + KVSO_REGISTER_HANDLER(KvsObject_file,"writeBlock", writeBlock) + + KVSO_REGISTER_HANDLER(KvsObject_file,"readHexBlock",readHexBlock) + KVSO_REGISTER_HANDLER(KvsObject_file,"writeHexBlock",writeHexBlock) + + KVSO_REGISTER_HANDLER(KvsObject_file,"readLine",readLine) + KVSO_REGISTER_HANDLER(KvsObject_file,"writeLine",writeLine) + + KVSO_REGISTER_HANDLER(KvsObject_file,"write",write) + KVSO_REGISTER_HANDLER(KvsObject_file,"read",read) + + +KVSO_END_REGISTERCLASS(KvsObject_file) + + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_file,KvsObject_widget) + m_pFile = new KviFile(); + +KVSO_END_CONSTRUCTOR(KvsObject_file) + +KVSO_BEGIN_DESTRUCTOR(KvsObject_file) + + if (m_pFile) delete m_pFile; + +KVSO_END_CONSTRUCTOR(KvsObject_file) + +KVSO_CLASS_FUNCTION(file,setName) +{ + CHECK_INTERNAL_POINTER(m_pFile) + QString szName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("file_name",KVS_PT_STRING,0,szName) + KVSO_PARAMETERS_END(c) + m_pFile->setFileName(szName); + return true; +} + +KVSO_CLASS_FUNCTION(file,name) +{ + CHECK_INTERNAL_POINTER(m_pFile) + c->returnValue()->setString(m_pFile->fileName()); + return true; +} + +KVSO_CLASS_FUNCTION(file,open) +{ + CHECK_INTERNAL_POINTER(m_pFile) + QStringList modes; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("file_mode",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,modes) + KVSO_PARAMETERS_END(c) + + if(m_pFile->fileName().isEmpty()) + { + c->warning(__tr2qs_ctx("Empty filename string","objects")); + return true; + } + QIODevice::OpenMode mod,sum; + if (modes.empty()) sum = QIODevice::ReadWrite|QIODevice::Append; // if no parameters given, default to ReadWrite | Append + else + { + for ( int idx=0;idxwarning(__tr2qs_ctx("No such open mode '%Q'","objects"),&modes.at(idx)); + } + } + c->returnValue()->setBoolean(m_pFile->open(sum)); + return true; +} + +KVSO_CLASS_FUNCTION(file,isOpen) +{ + CHECK_INTERNAL_POINTER(m_pFile) + c->returnValue()->setBoolean(m_pFile->isOpen()); + return true; +} + +KVSO_CLASS_FUNCTION(file,close) +{ + CHECK_INTERNAL_POINTER(m_pFile) + CHECK_FILE_IS_OPEN + m_pFile->close(); + return true; +} + +KVSO_CLASS_FUNCTION(file,flush) +{ + CHECK_INTERNAL_POINTER(m_pFile) + CHECK_FILE_IS_OPEN + m_pFile->flush(); + return true; +} + +KVSO_CLASS_FUNCTION(file,size) +{ + CHECK_INTERNAL_POINTER(m_pFile) + c->returnValue()->setInteger((kvs_int_t)(m_pFile->size())); + return true; +} + +KVSO_CLASS_FUNCTION(file,atEnd) +{ + CHECK_INTERNAL_POINTER(m_pFile) + c->returnValue()->setInteger((kvs_int_t)(m_pFile->atEnd())); + return true; +} + +KVSO_CLASS_FUNCTION(file,where) +{ + CHECK_INTERNAL_POINTER(m_pFile) + CHECK_FILE_IS_OPEN + c->returnValue()->setInteger((kvs_int_t)(m_pFile->pos())); + return true; +} + +KVSO_CLASS_FUNCTION(file,seek) +{ + CHECK_INTERNAL_POINTER(m_pFile) + kvs_uint_t uIndex; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex) + KVSO_PARAMETERS_END(c) + CHECK_FILE_IS_OPEN + m_pFile->seek(uIndex); + return true; +} + + +KVSO_CLASS_FUNCTION(file,resize) +{ + CHECK_INTERNAL_POINTER(m_pFile) + kvs_int_t iSize; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("size",KVS_PT_INTEGER,0,iSize) + KVSO_PARAMETERS_END(c) + CHECK_FILE_IS_OPEN + m_pFile->resize(iSize); + return true; +} + +KVSO_CLASS_FUNCTION(file,putch) +{ + CHECK_INTERNAL_POINTER(m_pFile) + QString szChar; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("char",KVS_PT_STRING,0,szChar) + KVSO_PARAMETERS_END(c) + if (szChar.length()>1)c->warning(__tr2qs_ctx("Argument too long, using only first char","objects")); + const char *ch=szChar.toUtf8().data(); + if (!m_pFile->putChar(ch[0])) c->warning(__tr2qs_ctx("Write error occured!","objects")); + return true; +} + +KVSO_CLASS_FUNCTION(file,getch) +{ + CHECK_INTERNAL_POINTER(m_pFile) + CHECK_FILE_IS_OPEN + char ch; + if (!m_pFile->getChar(&ch)) c->warning(__tr2qs_ctx("Read error occured!","objects")); // c->error ? + QString szChar = QChar(ch); + c->returnValue()->setString(szChar); + return true; +} + +KVSO_CLASS_FUNCTION(file,readByte) +{ + CHECK_INTERNAL_POINTER(m_pFile) + CHECK_FILE_IS_OPEN + char ch; + if (!m_pFile->getChar(&ch)) c->warning(__tr2qs_ctx("Read error occured!","objects")); // c->error ? + //QString szChar = QChar(ch); + c->returnValue()->setInteger((kvs_int_t) ch); + return true; +} + +KVSO_CLASS_FUNCTION(file,unGetch) +{ + CHECK_INTERNAL_POINTER(m_pFile) + CHECK_FILE_IS_OPEN + QString szChar; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("char",KVS_PT_STRING,0,szChar) + KVSO_PARAMETERS_END(c) + if (szChar.length()>1) c->warning(__tr2qs_ctx("Argument too long, using only the first char","objects")); + const char *ch=szChar.toUtf8().data(); + m_pFile->ungetChar(ch[0]); + return true; +} + +KVSO_CLASS_FUNCTION(file,readBlock) +{ + CHECK_INTERNAL_POINTER(m_pFile) + CHECK_FILE_IS_OPEN + kvs_uint_t uLen; + KviKvsObject * pObject; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("length",KVS_PT_UNSIGNEDINTEGER,0,uLen) + KVSO_PARAMETER("hobject",KVS_PT_HOBJECT,KVS_PF_OPTIONAL,hObject) + KVSO_PARAMETERS_END(c) + if (uLen>(kvs_uint_t)m_pFile->size()) uLen=m_pFile->size(); + if (hObject) + { + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + if (!pObject) + { + c->warning(__tr2qs_ctx("Buffer parameter is not an object","objects")); + return true; + } + if (!pObject->inheritsClass("memorybuffer")) + { + c->warning(__tr2qs_ctx("Buffer parameter is not a memorybuffer object","objects")); + return true; + } + //m_pFile->flush(); + ((KvsObject_memoryBuffer *)pObject)->pBuffer()->append(m_pFile->read(uLen)); + return true; + } + else + { + char * buff = new char[uLen + 1]; + //m_pFile->flush(); // advice from QFile man page (to avoid trash) + int rlen = m_pFile->read(buff, uLen); + buff[rlen] = '\0'; + QString szBlock(buff); + c->returnValue()->setString(szBlock); + } + return true; +} + +KVSO_CLASS_FUNCTION(file,read) +{ + CHECK_INTERNAL_POINTER(m_pFile) + CHECK_FILE_IS_OPEN + QString szType; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("type",KVS_PT_STRING,0,szType) + KVSO_PARAMETERS_END(c) + if(KviQString::equalCI(szType, "String")) + { + QString szStr; + m_pFile->load(szStr); + c->returnValue()->setString(szStr); + } + else if(KviQString::equalCI(szType, "Integer")) + { + int iValue; + m_pFile->load(iValue); + c->returnValue()->setInteger(iValue); + } + else if(KviQString::equalCI(szType, "Array")) + { + QString szData; + m_pFile->load(szData); + KviKvsVariant *pVar = KviKvsVariant::unserialize(szData); + if (pVar->isArray()) + c->returnValue()->setArray(pVar->array()); + else + c->warning(__tr2qs_ctx("The incoming data isn't an array","objects")); + } + else if(KviQString::equalCI(szType, "Dict")) + { + QString szData; + m_pFile->load(szData); + KviKvsVariant *pVar = KviKvsVariant::unserialize(szData); + if (pVar->isHash()) + c->returnValue()->setHash(pVar->hash()); + else + c->warning(__tr2qs_ctx("The incoming data isn't a Dictionary","objects")); + } + else if(KviQString::equalCI(szType, "String")) + { + QString szStr; + m_pFile->load(szStr); + c->returnValue()->setString(szStr); + } + else + { + c->warning(__tr2qs_ctx("Unsupported datatype '%Q'","objects"),&szType); + } + return true; +} + +KVSO_CLASS_FUNCTION(file,write) +{ + CHECK_INTERNAL_POINTER(m_pFile) + CHECK_FILE_IS_OPEN + KviKvsVariant * pVariantData; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("variant_data",KVS_PT_VARIANT,0,pVariantData) + KVSO_PARAMETERS_END(c) + if (pVariantData->isInteger()) + { + kvs_int_t num; + pVariantData->asInteger(num); + m_pFile->save(num); + } + if (pVariantData->isHash() || pVariantData->isArray() || pVariantData->isString()) + { + QString szTmp; + pVariantData->serialize(szTmp); + m_pFile->save(szTmp); + } + return true; +} + +KVSO_CLASS_FUNCTION(file,writeBlock) +{ + CHECK_INTERNAL_POINTER(m_pFile) + kvs_uint_t uLen; + KviKvsObject * pObject; + KviKvsVariant * pVariantData; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("string_or_hobject",KVS_PT_VARIANT,0,pVariantData) + KVSO_PARAMETER("length",KVS_PT_UNSIGNEDINTEGER,KVS_PF_OPTIONAL,uLen) + KVSO_PARAMETERS_END(c) + if(!m_pFile->isOpen())c->warning(__tr2qs_ctx("File is not open!","objects")); + else + { + if (pVariantData->isHObject()) + { + pVariantData->asHObject(hObject); + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + if (!pObject) + { + c->warning(__tr2qs_ctx("Buffer parameter is not an object","objects")); + return true; + } + if (pObject->inheritsClass("memorybuffer")) + { + if (!uLen) + { + if (((KvsObject_memoryBuffer *)pObject)->pBuffer()->size()) + uLen=((KvsObject_memoryBuffer *)pObject)->pBuffer()->size(); + else + { + c->warning(__tr2qs_ctx("The memoryBuffer object is empty: nothing will be saved","objects")); + } + } + const char *pData=((KvsObject_memoryBuffer *)pObject)->pBuffer()->data(); + int rlen=m_pFile->write(pData,uLen); + c->returnValue()->setInteger(rlen); + //m_pFile->flush(); + } else { + c->warning(__tr2qs_ctx("Buffer parameter is not a memorybuffer object","objects")); + return true; + } + + } + else + { + if (!pVariantData->isString()){ + c->warning(__tr2qs_ctx("Block parameter must be a string or a memorybuffer object","objects")); + return true; + } + QString szBlock; + pVariantData->asString(szBlock); + const char *block=szBlock.toUtf8().data(); + int rlen = m_pFile->write(block, uLen); + c->returnValue()->setInteger(rlen); + //m_pFile->flush(); + } + } + return true; +} + +KVSO_CLASS_FUNCTION(file,readLine) +{ + CHECK_INTERNAL_POINTER(m_pFile) + CHECK_FILE_IS_OPEN + QString buffer; + //bool ok=KviFileUtils::readLine(m_pFile,buffer); + buffer=m_pFile->readLine(); + c->returnValue()->setString(buffer); + return true; +} + +KVSO_CLASS_FUNCTION(file,writeLine) +{ + CHECK_INTERNAL_POINTER(m_pFile) + CHECK_FILE_IS_OPEN + QString szLine; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text_line",KVS_PT_STRING,0,szLine) + KVSO_PARAMETERS_END(c) + QTextStream ts(m_pFile); + ts << szLine; + return true; +} + +KVSO_CLASS_FUNCTION(file,readHexBlock) +{ + CHECK_INTERNAL_POINTER(m_pFile) + CHECK_FILE_IS_OPEN + kvs_uint_t uLen; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("lenght",KVS_PT_UNSIGNEDINTEGER,0,uLen) + KVSO_PARAMETERS_END(c) + if (uLen>(kvs_uint_t)m_pFile->size()) uLen=m_pFile->size(); + char * buff = new char[uLen]; + char * str = new char [(uLen*2)+1]; + m_pFile->flush(); // advice from QFile man page (to avoid trash) + int rlen = m_pFile->read(buff, uLen); + int index=0; + unsigned char byte,msb,lsb=0; + for (int i=0;i>4; + msb>9?msb+='7':msb+='0'; + lsb>9?lsb+='7':lsb+='0'; + str[index++]=msb; + str[index++]=lsb; + } + str[index]='\0'; + c->returnValue()->setString(str); + delete[] str; + delete[] buff; + return true; +} + +KVSO_CLASS_FUNCTION(file,writeHexBlock) +{ + CHECK_INTERNAL_POINTER(m_pFile) + CHECK_FILE_IS_OPEN + QString szBlock; + kvs_uint_t uLen; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text_block",KVS_PT_STRING,0,szBlock) + KVSO_PARAMETER("lenght",KVS_PT_UNSIGNEDINTEGER,KVS_PF_OPTIONAL,uLen) + KVSO_PARAMETERS_END(c) + if (szBlock.length()%2) + { + c->warning(__tr2qs_ctx("Length of hex string is not multiple of 2","objects")); + return true; + } + if (uLen>((uint)szBlock.length()/2)|| !uLen) uLen=szBlock.length(); + else uLen*=2; + unsigned char byte,lsb,msb; + for(unsigned int i=0;i='A' && msb<='F')||(msb>='0' && msb<='9')) && ((lsb>='A' && lsb<='F')|| (lsb>='0' && lsb<='9'))) + { + msb>='A'?msb-='7':msb-='0'; + lsb>='A'?lsb-='7':lsb-='0'; + } else{ + c->warning(__tr2qs_ctx("The hex string is not correct!","objects")); + return true; + } + byte=(msb*16)+lsb; + m_pFile->putChar(byte); + } + c->returnValue()->setInteger(uLen/2); + return true; +} diff --git a/src/modules/objects/KvsObject_file.h b/src/modules/objects/KvsObject_file.h new file mode 100644 index 000000000..b226c10b0 --- /dev/null +++ b/src/modules/objects/KvsObject_file.h @@ -0,0 +1,74 @@ +#ifndef _CLASS_FILE_H_ +#define _CLASS_FILE_H_ +//============================================================================= +// +// File : KvsObject_memoryBuffer.h +// Creation date : Fri Mar 18 21:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2009 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "object_macros.h" +#include "KvsObject_widget.h" +#include "KviFile.h" + + +class KvsObject_file : public KvsObject_widget +{ +public: + KVSO_DECLARE_OBJECT(KvsObject_file) +protected: + KviFile * m_pFile; +public: + + KviFile * file(){ return m_pFile; }; + bool setName(KviKvsObjectFunctionCall *c); + bool name(KviKvsObjectFunctionCall *c); + bool open(KviKvsObjectFunctionCall *c); + bool isOpen(KviKvsObjectFunctionCall *c); + bool close(KviKvsObjectFunctionCall *c); + bool flush(KviKvsObjectFunctionCall *c); + bool size(KviKvsObjectFunctionCall *c); + bool resize(KviKvsObjectFunctionCall *c); + + bool atEnd(KviKvsObjectFunctionCall *c); + // int QFile at() const + bool where(KviKvsObjectFunctionCall *c); + // void QFile at(int) + bool seek(KviKvsObjectFunctionCall *c); + bool putch(KviKvsObjectFunctionCall *c); + bool getch(KviKvsObjectFunctionCall *c); + bool readByte(KviKvsObjectFunctionCall *c); + bool unGetch(KviKvsObjectFunctionCall *c); + + bool readBlock(KviKvsObjectFunctionCall *c); + bool writeBlock(KviKvsObjectFunctionCall *c); + + bool readLine(KviKvsObjectFunctionCall *c); + bool writeLine(KviKvsObjectFunctionCall *c); + + bool readHexBlock(KviKvsObjectFunctionCall *c); + bool writeHexBlock(KviKvsObjectFunctionCall *c); + + bool write(KviKvsObjectFunctionCall *c); + bool read(KviKvsObjectFunctionCall *c); +}; + +#endif // !_CLASS_FILE_H_ diff --git a/src/modules/objects/KvsObject_ftp.cpp b/src/modules/objects/KvsObject_ftp.cpp new file mode 100644 index 000000000..9face909f --- /dev/null +++ b/src/modules/objects/KvsObject_ftp.cpp @@ -0,0 +1,327 @@ +//============================================================================= +// +// File : KvsObject_ftp.cpp +// Creation date : Mon Sep 1 08:13:45 2008 GMT by Carbone Alesssandro +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2009 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_debug.h" +#include "KviError.h" +#include "KvsObject_ftp.h" +#include "KviLocale.h" + +#include +#include + + +/* + @doc: ftp + @keyterms: + ftp object class + @title: + ftp class + @type: + class + @short: + An implementation of the client side of FTP protocol. + @inherits: + [class]object[/class] + @description: + This class provides a standard FTP functionality.[br] + @functions: + !fn:$dataAvailableEvent() + This function is called when some data is available to be read: the parameter specifies + the length of the available data in bytes.[br] + You can use one of the $read* functions to obtain the data. + !fn: $connect(,) + Connects to the FTP server host using port port.The command is scheduled, and its execution is performed asynchronously. + The function returns a unique identifier which is passed by commandStarted() and commandFinished().[br] + !fn:$abort() + Aborts the current command and deletes all scheduled commands. + !fn: $login(,) + Logs in to the FTP server with the username user and the password . + The function returns a unique identifier which is passed by commandStarted() and commandFinished().[br] + !fn: $get(,) + Downloads the file from the server. + !fn: $cd() + Changes the working directory of the server to . + !fn: $list() + Lists the contents of directory dir on the FTP server. + !fn: $commandFinishedEvent(,) + Called by KVIrc when the ftp command identified by id has finished. + error is true if an error occurred during the processing; otherwise error is false. + The default implementation emits the [classfnc]$commandFinished[/classfnc]() signal. + !fn: $listInfoEvent() + This event is triggered for each directory entry found by [classfnc]$list[/classfnc]() command. + The default implementation emits the [classfnc]$listInfo[/classfnc]() signal. + !fn: $dataTransferProgressEvent(,) + This event is triggered in response to a [classfnc]get[/classfnc]() or [classfnc]put[/classfnc]() request to indicate the current progress of the download or upload. + The default implementation emits the [classfnc]$dataTransferProgress[/classfnc]() signal. + @signals: + !sg: $commandFinished(,,) + This signal is emitted by the default implementation of [classfnc]$commandFinishedEvent[/classfnc]() + !sg: $listInfo() + This signal is emitted by the default implementation of [classfnc]$listInfoEvent[/classfnc]() + !sg: $dataTransferProgress(,) + This signal is emitted by the default implementation of [classfnc]$dataTransferProgressEvent[/classfnc]() +*/ + +KVSO_BEGIN_REGISTERCLASS(KvsObject_ftp,"ftp","object") + KVSO_REGISTER_HANDLER(KvsObject_ftp,"connect",functionConnect) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_ftp,abort) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_ftp,close) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_ftp,close) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_ftp,login) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_ftp,get) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_ftp,cd) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_ftp,list) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_ftp,commandFinishedEvent) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_ftp,listInfoEvent) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_ftp,stateChangedEvent) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_ftp,dataTransferProgressEvent) +KVSO_END_REGISTERCLASS(KvsObject_ftp) + + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_ftp,KviKvsObject) + m_pFtp = new QFtp(); + m_bAbort=false; + connect(m_pFtp,SIGNAL(commandFinished(int,bool)),this,SLOT(slotCommandFinished(int,bool))); + connect(m_pFtp,SIGNAL(commandStarted(int)),this,SLOT(slotCommandStarted(int))); + connect(m_pFtp,SIGNAL(dataTransferProgress(qint64,qint64)),this,SLOT(slotDataTransferProgress(qint64,qint64))); + connect(m_pFtp,SIGNAL(done(bool)),this,SLOT(slotDone(bool))); + connect(m_pFtp,SIGNAL(listInfo(const QUrlInfo)),this,SLOT(slotListInfo(const QUrlInfo))); + connect(m_pFtp,SIGNAL(readyRead()),this,SLOT(slotReadyRead())); + connect(m_pFtp,SIGNAL(stateChanged(int)),this,SLOT(slotStateChanged(int))); +KVSO_END_CONSTRUCTOR(KvsObject_ftp) + +KVSO_BEGIN_DESTRUCTOR(KvsObject_ftp) + QHashIterator t(getDict); + while (t.hasNext()) + { + t.next(); + int key=t.key(); + QFile *pFile=getDict.value(key); + pFile->close(); + delete pFile; + } + getDict.clear(); + delete m_pFtp; +KVSO_END_DESTRUCTOR(KvsObject_ftp) +//---------------------- + + + +KVSO_CLASS_FUNCTION(ftp,functionConnect) +{ + CHECK_INTERNAL_POINTER(m_pFtp) + QString szHost; + kvs_uint_t uRemotePort; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("host",KVS_PT_STRING,0,szHost) + KVSO_PARAMETER("remote_port",KVS_PT_UNSIGNEDINTEGER,KVS_PF_OPTIONAL,uRemotePort) + KVSO_PARAMETERS_END(c) + if (!uRemotePort) uRemotePort=21; + kvs_uint_t id=0; + id=m_pFtp->connectToHost(szHost, uRemotePort); + c->returnValue()->setInteger(id); + return true; +} + +KVSO_CLASS_FUNCTION(ftp,login) +{ + CHECK_INTERNAL_POINTER(m_pFtp) + QString szUser,szPass; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("user",KVS_PT_STRING,0,szUser) + KVSO_PARAMETER("password",KVS_PT_STRING,0,szPass) + KVSO_PARAMETERS_END(c) + int id=m_pFtp->login(szUser, szPass); + c->returnValue()->setInteger(id); + return true; +} + +KVSO_CLASS_FUNCTION(ftp,get) +{ + CHECK_INTERNAL_POINTER(m_pFtp) + QString szFile,szDest; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("remote_filename",KVS_PT_STRING,0,szFile) + KVSO_PARAMETER("local_filename",KVS_PT_STRING,0,szDest) + KVSO_PARAMETERS_END(c) + QFile *pFile; + pFile=new QFile(szDest); + pFile->open(QIODevice::WriteOnly); + int id=0; + id=m_pFtp->get(szFile,pFile); + getDict[id]=pFile; + c->returnValue()->setInteger(id); + return true; +} + +KVSO_CLASS_FUNCTION(ftp,cd) +{ + CHECK_INTERNAL_POINTER(m_pFtp) + QString szPath; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("remote_filename",KVS_PT_STRING,0,szPath) + KVSO_PARAMETERS_END(c) + int id=m_pFtp->cd(szPath); + c->returnValue()->setInteger(id); + return true; +} + +KVSO_CLASS_FUNCTION(ftp,list) +{ + CHECK_INTERNAL_POINTER(m_pFtp) + QString szPath; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("remote_dir",KVS_PT_STRING,0,szPath) + KVSO_PARAMETERS_END(c) + int id=m_pFtp->list(szPath); + c->returnValue()->setInteger(id); + return true; +} + +KVSO_CLASS_FUNCTION(ftp,abort) +{ + CHECK_INTERNAL_POINTER(m_pFtp) + m_bAbort=true; + m_pFtp->abort(); + return true; +} + +KVSO_CLASS_FUNCTION(ftp,close) +{ + CHECK_INTERNAL_POINTER(m_pFtp) + m_bAbort=true; + m_pFtp->close(); + return true; +} + +//signals & slots +KVSO_CLASS_FUNCTION(ftp,commandFinishedEvent) +{ + emitSignal("commandFinished",c,c->params()); + return true; +} + +void KvsObject_ftp::slotCommandFinished ( int id, bool error ) +{ + QString status=""; + if (m_bAbort) + { + m_bAbort=false; + QHashIterator t(getDict); + while (t.hasNext()) + { + t.next(); + int key=t.key(); + QFile *pFile=getDict.value(key); + pFile->close(); + delete pFile; + } + getDict.clear(); + return; + } + if (m_pFtp->currentCommand()==QFtp::Get) + { + status="Downloaded"; + QFile *pFile=getDict.value(id); + pFile->close(); + delete pFile; + getDict.remove(id); + } + else if (m_pFtp->currentCommand()==QFtp:: ConnectToHost) status="connected"; + else if (m_pFtp->currentCommand()==QFtp:: Login) status="logged"; + else if (m_pFtp->currentCommand()==QFtp:: Cd) status="entered"; + else if (m_pFtp->currentCommand()==QFtp:: List) status="listCompleted"; + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant((kvs_int_t) id)); + lParams.append(new KviKvsVariant(status)); + lParams.append(new KviKvsVariant(error)); + callFunction(this,"commandFinishedEvent",0,&lParams); +} + +void KvsObject_ftp::slotCommandStarted ( int ) +{ +} + +void KvsObject_ftp::slotDataTransferProgress ( qint64 done, qint64 total ) +{ + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant((kvs_int_t) done)); + lParams.append(new KviKvsVariant((kvs_int_t) total)); + callFunction(this,"dataTransferProgressEvent",0,&lParams); +} + +KVSO_CLASS_FUNCTION(ftp,dataTransferProgressEvent) +{ + emitSignal("dataTransferProgress",c,c->params()); + return true; +} + +void KvsObject_ftp::slotDone ( bool ) +{ +} + +void KvsObject_ftp::slotListInfo ( const QUrlInfo & i ) +{ + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant(i.name())); + callFunction(this,"listInfoEvent",0,&lParams); +} + +KVSO_CLASS_FUNCTION(ftp,listInfoEvent) +{ + emitSignal("listInfo",c,c->params()); + return true; +} + +void KvsObject_ftp::slotReadyRead () +{ +} + +void KvsObject_ftp::slotRawCommandReply (int, const QString & ) +{ +} + +void KvsObject_ftp::slotStateChanged (int state) +{ + QString szState=""; + if (state==QFtp::Unconnected) szState="Unconnected"; + else if (state==QFtp::HostLookup) szState="HostLookup"; + else if (state==QFtp::Connecting) szState="Connecting"; + else if (state==QFtp::Connected) szState="Connected"; + else if (state==QFtp::LoggedIn) szState="LoggedIn"; + else if (state==QFtp::Closing) szState="Closing"; + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant(szState)); + callFunction(this,"stateChangedEvent",0,&lParams); +} + +KVSO_CLASS_FUNCTION(ftp,stateChangedEvent) +{ + emitSignal("stateChanged",c,c->params()); + return true; +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_ftp.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/objects/KvsObject_ftp.h b/src/modules/objects/KvsObject_ftp.h new file mode 100644 index 000000000..c50942fd1 --- /dev/null +++ b/src/modules/objects/KvsObject_ftp.h @@ -0,0 +1,64 @@ +#ifndef _CLASS_FTP_H_ +#define _CLASS_FTP_H_ +//============================================================================= +// +// File : KvsObject_ftp.h +// Creation date : Mon Sep 1 08:13:45 2008 GMT by Carbone Alesssandro +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2009 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "object_macros.h" + +#include +#include +#include + +class KvsObject_ftp : public KviKvsObject +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_ftp) +protected: + QFtp *m_pFtp; + QHash getDict; + bool m_bAbort; +protected: + bool functionConnect(KviKvsObjectFunctionCall *c); + bool get(KviKvsObjectFunctionCall *c); + bool login(KviKvsObjectFunctionCall *c); + bool cd(KviKvsObjectFunctionCall *c); + bool list(KviKvsObjectFunctionCall *c); + bool dataTransferProgressEvent(KviKvsObjectFunctionCall *c); + bool listInfoEvent(KviKvsObjectFunctionCall *c); + bool commandFinishedEvent(KviKvsObjectFunctionCall *c); + bool stateChangedEvent(KviKvsObjectFunctionCall *c); + bool abort(KviKvsObjectFunctionCall *c); + bool close(KviKvsObjectFunctionCall *c); +protected slots: + void slotCommandFinished ( int id, bool error ); + void slotCommandStarted ( int id ); + void slotDataTransferProgress ( qint64 done, qint64 total ); + void slotDone ( bool error ); + void slotListInfo ( const QUrlInfo & i ); + void slotRawCommandReply ( int replyCode, const QString & detail ); + void slotReadyRead (); + void slotStateChanged ( int state); +}; +#endif //_CLASS_FTP_H_ diff --git a/src/modules/objects/KvsObject_groupBox.cpp b/src/modules/objects/KvsObject_groupBox.cpp new file mode 100644 index 000000000..03042d795 --- /dev/null +++ b/src/modules/objects/KvsObject_groupBox.cpp @@ -0,0 +1,335 @@ +//============================================================================= +// +// File : KvsObject_groupBox.cpp +// Creation date : Fri Jan 28 14:21:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2009 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include +#include "KvsObject_groupBox.h" +#include "KviError.h" +#include "kvi_debug.h" + +#include "KviLocale.h" +#include "KviIconManager.h" + + +// Tables used in $setAlignment, $alignment and in $setOrientation & $orientation + +const char * const align_tbl[] = { + "Left", + "Right", + "HCenter" +}; + +const int align_cod[] = { + Qt::AlignLeft, + Qt::AlignRight, + Qt::AlignHCenter +}; + +#define align_num (sizeof(align_tbl) / sizeof(align_tbl[0])) + + +/* + @doc: groupbox + @keyterms: + groupbox object class, + @title: + groupbox class + @type: + class + @short: + Provides a groupbox bar. + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + This widget can be used to display a groupbox. + It will be usually a parent for other child controls. + You can either use a child layout to manage the children geometries + or use $setColumnLayout to manage the layout automatically. + @functions: + !fn: $setTitle() + Sets the group box title to . + !fn: $title() + Returns the group box title text. + !fn: $setFlat() + Sets whether the group box is painted flat. Valid Values are 1 or 0. + !fn: $isFlat() + Returns 1 (TRUE) if the group box is painted flat; otherwise returns 0 (FALSE). + !fn: $isCheckable() + Returns 1 (TRUE) if the group box has a checkbox in its title; otherwise returns 0 (FALSE). + !fn: $setCheckable() + Sets whether the group box has a checkbox in its title: Valid values are 1 or 0. + !fn: $setInsideMargin() + Sets the the width of the inside margin to m pixels. + !fn: $insideMargin() + Returns the width of the empty space between the items in the group and margin of groupbox. + !fn: $setInsideSpacing() + Sets the width of the empty space between each of the items in the group to m pixels. + !fn: $insideSpacing() + Returns the width of the empty space between each of the items in the group. + !fn: $addSpace() + Adds an empty cell at the next free position. + !fn: $alignment() + Returns the alignment of the group box title. + !fn: $setAlignment() + Set the alignment of the groupbox; Valid values are Left,Right,HCenter. + !fn: $setOrientation + Sets the group box's orientation. Valid values are: Horizontal, Vertical. + @examples: + [example] + //Let's start. + //First we'll create the main widget. as a dialog + %widget=$new(dialog) + %layout=$new(layout,%widget) + //then the groupbox + %gb=$new(groupbox,%widget) + %gb->$setTitle(Login) + %gb->$setAlignment("Left") + // add the gbox to the main layout + %layout->$addWidget(%gb,0,0) + // now we create the user field (labels + lineedit) + // in a horizontal box + %hbox=$new(hbox,%gb) + %labeluser=$new(label,%hbox) + %labeluser->$settext(User: ) + %inputuser=$new(lineedit,%hbox) + //now we create the pass field (labels + lineedit). + // in a horizontal box + %hbox=$new(hbox,%gb) + %labelpass=$new(label,%hbox) + %labelpass->$settext(Pass: ) + %inputpass=$new(lineedit,%hbox) + %inputpass->$setechomode("password") + // now we create the ok/cancel box buttons + %hbox=$new(hbox,%gb) + %btnok=$new(button,%hbox) + %btnok->$settext("OK") + %btncancel=$new(button,%hbox) + %btncancel->$settext("Cancel") + + //Let's show our nice form + %widget->$show() + [/example] + +*/ + +KVSO_BEGIN_REGISTERCLASS(KvsObject_groupBox,"groupbox","widget") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_groupBox,setTitle) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_groupBox,title) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_groupBox,setFlat) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_groupBox,isFlat) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_groupBox,setCheckable) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_groupBox,isCheckable) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_groupBox,setInsideMargin) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_groupBox,insideMargin) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_groupBox,setInsideSpacing) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_groupBox,insideSpacing) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_groupBox,addSpace) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_groupBox,alignment) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_groupBox,setAlignment) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_groupBox,setOrientation) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_groupBox,isChecked) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_groupBox,setChecked) + +KVSO_END_REGISTERCLASS(KvsObject_groupBox) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_groupBox,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_groupBox) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_groupBox) + +KVSO_END_CONSTRUCTOR(KvsObject_groupBox) + +bool KvsObject_groupBox::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + KviTalGroupBox *groupbox=new KviTalGroupBox(getName(),parentScriptWidget()); + + groupbox->setOrientation(Qt::Horizontal); + groupbox->setObjectName(getName()); + setObject(groupbox,true); + return true; +} + +KVSO_CLASS_FUNCTION(groupBox,setTitle) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szTitle; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("title",KVS_PT_STRING,0,szTitle) + KVSO_PARAMETERS_END(c) + ((KviTalGroupBox *)widget())->setTitle(szTitle); + return true; +} +KVSO_CLASS_FUNCTION(groupBox,title) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setString(((KviTalGroupBox *)widget())->title()); + return true; +} +KVSO_CLASS_FUNCTION(groupBox,setFlat) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bFlag",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + ((KviTalGroupBox *)widget())->setFlat(bEnabled); + return true; +} +KVSO_CLASS_FUNCTION(groupBox,isFlat) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setBoolean(((KviTalGroupBox *)widget())->isFlat()); + return true; +} +KVSO_CLASS_FUNCTION(groupBox,setCheckable) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bFlag",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + ((KviTalGroupBox *)widget())->setCheckable(bEnabled); + return true; +} +KVSO_CLASS_FUNCTION(groupBox,isCheckable) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setBoolean(((KviTalGroupBox *)widget())->isCheckable()); + return true; +} +KVSO_CLASS_FUNCTION(groupBox,setChecked) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bFlag",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + ((KviTalGroupBox *)widget())->setChecked(bEnabled); + return true; +} +KVSO_CLASS_FUNCTION(groupBox,isChecked) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setBoolean(((KviTalGroupBox *)widget())->isChecked()); + return true; +} +KVSO_CLASS_FUNCTION(groupBox,setInsideMargin) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uMargin; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("margin",KVS_PT_UNSIGNEDINTEGER,0,uMargin) + KVSO_PARAMETERS_END(c) + ((KviTalGroupBox *)widget())->setInsideMargin(uMargin); + return true; +} +KVSO_CLASS_FUNCTION(groupBox,insideMargin) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((KviTalGroupBox *)widget())->insideMargin()); + return true; +} +KVSO_CLASS_FUNCTION(groupBox,setInsideSpacing) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uSpacing; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("spacing",KVS_PT_UNSIGNEDINTEGER,0,uSpacing) + KVSO_PARAMETERS_END(c) + ((KviTalGroupBox *)widget())->setInsideSpacing(uSpacing); + return true; +} +KVSO_CLASS_FUNCTION(groupBox,insideSpacing) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((KviTalGroupBox *)widget())->insideSpacing()); + return true; +} + +KVSO_CLASS_FUNCTION(groupBox,addSpace) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t iSpace; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("colums",KVS_PT_UNSIGNEDINTEGER,0,iSpace) + KVSO_PARAMETERS_END(c) + (((KviTalGroupBox *)widget())->addSpace(iSpace)); + return true; +} + +KVSO_CLASS_FUNCTION(groupBox,setAlignment) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szAlign; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("alignment",KVS_PT_STRING,0,szAlign) + KVSO_PARAMETERS_END(c) + for(unsigned int i = 0; i < align_num; i++) + { + if(KviQString::equalCI(szAlign, align_tbl[i])) + { + ((KviTalGroupBox *)widget())->setAlignment(align_cod[i]); + return true; + } + } + c->warning(__tr2qs_ctx("Unknown alignment '%Q'","objets"),&szAlign); + return true; +} + +KVSO_CLASS_FUNCTION(groupBox,alignment) +{ + CHECK_INTERNAL_POINTER(widget()) + int mode = ((KviTalGroupBox *)widget())->alignment(); + QString szAlignment=""; + for(unsigned int i = 0; i < align_num; i++) + { + if(mode == align_cod[i]) + { + szAlignment=align_tbl[i]; + break; + } + } + c->returnValue()->setString(szAlignment); + return true; +} + +KVSO_CLASS_FUNCTION(groupBox,setOrientation) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szMode; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("orientation",KVS_PT_STRING,0,szMode) + KVSO_PARAMETERS_END(c) + if(KviQString::equalCI(szMode, "Horizontal")) + ((KviTalGroupBox *)widget())->setOrientation(Qt::Vertical); + else + if(KviQString::equalCI(szMode, "Vertical")) + ((KviTalGroupBox *)widget())->setOrientation(Qt::Horizontal); + else c->warning( __tr2qs_ctx("Unknown orientation '%Q'","objects"),&szMode); + + return true; +} diff --git a/src/modules/objects/KvsObject_groupBox.h b/src/modules/objects/KvsObject_groupBox.h new file mode 100644 index 000000000..4770352a9 --- /dev/null +++ b/src/modules/objects/KvsObject_groupBox.h @@ -0,0 +1,63 @@ +#ifndef _CLASS_GROUPBOX_H_ +#define _CLASS_GROUPBOX_H_ +//============================================================================= +// +// File : KvsObject_groupBox.cpp +// Creation date : Fri Jan 28 14:21:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2009 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + + +#include +#include "KvsObject_widget.h" +#include "object_macros.h" + +class KvsObject_groupBox : public KvsObject_widget +{ +public: + KVSO_DECLARE_OBJECT(KvsObject_groupBox) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + + bool setTitle(KviKvsObjectFunctionCall *c); + bool title(KviKvsObjectFunctionCall *c); + bool setFlat(KviKvsObjectFunctionCall *c); + bool isFlat(KviKvsObjectFunctionCall *c); + bool setCheckable(KviKvsObjectFunctionCall *c); + bool isCheckable(KviKvsObjectFunctionCall *c); + bool setInsideMargin(KviKvsObjectFunctionCall *c); + bool insideMargin(KviKvsObjectFunctionCall *c); + bool setInsideSpacing(KviKvsObjectFunctionCall *c); + bool insideSpacing(KviKvsObjectFunctionCall *c); + bool addSpace(KviKvsObjectFunctionCall *c); + bool alignment(KviKvsObjectFunctionCall *c); + bool setAlignment(KviKvsObjectFunctionCall *c); + bool setOrientation(KviKvsObjectFunctionCall *c); + bool isChecked(KviKvsObjectFunctionCall *c); + bool setChecked(KviKvsObjectFunctionCall *c); + +}; +#endif //!_CLASS_GROUPBOX_H_ + diff --git a/src/modules/objects/KvsObject_hBox.cpp b/src/modules/objects/KvsObject_hBox.cpp new file mode 100644 index 000000000..c9c5b53fb --- /dev/null +++ b/src/modules/objects/KvsObject_hBox.cpp @@ -0,0 +1,202 @@ +//============================================================================= +// +// File : KvsObject_hBox.cpp +// Creation date : Wed Mar 01 2005 23:00:01 by Alessandro Carbone & Tonino Imbesi +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2009 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#define _KVI_DEBUG_CHECK_RANGE_ +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KvsObject_hBox.h" +#include "KviTalHBox.h" + +const char * const align_tbl[] = { + "Left", + "Right", + "HCenter", + "VCenter", + "Center", + "Top", + "Bottom", + "WordBreak" +}; + + + +const int align_cod[] = { + Qt::AlignLeft, + Qt::AlignRight, + Qt::AlignHCenter, + Qt::AlignVCenter, + Qt::AlignCenter, + Qt::AlignTop, + Qt::AlignBottom, + Qt::AlignJustify, +}; + +#define align_num (sizeof(align_tbl) / sizeof(align_tbl[0])) + +/* + @doc: hbox + @keyterms: + hbox object class, child widgets + @title: + hbox class + @type: + class + @short: + Manages child widget horizontal geometry + @inherits: + [class]object[/class] + @description: + The hbox class widget provides horizontal geometry management for its child widgets. + @functions: + !fn: $setSpacing() + Sets the default spacing of the widgets in pixels + !fn: $setMargin() + Sets the dimension of the layout margin : the distance from the border to the outermost child widget edges. + !fn: $setStretchFactor(,) + Sets the stretch factor of widget to stretch. + !fn: $addStretch() + Adds a stretchable space with zero minimum size and stretch factor stretch to the end of this box layout. + !fn: $setAlignment(, , ...) + Sets the alignment for widget w to flags, given as parameters. + Valid flags are:Right,Left,Top,Bottom,HCenter,VCenter,Center +*/ + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_hBox,"hbox","widget") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_hBox,setMargin) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_hBox,setSpacing) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_hBox,setStretchFactor ) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_hBox,addStretch ) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_hBox,setAlignment ) +KVSO_END_REGISTERCLASS(KvsObject_hBox) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_hBox,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_hBox) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_hBox) + +KVSO_END_CONSTRUCTOR(KvsObject_hBox) + +bool KvsObject_hBox::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + + setObject(new KviTalHBox(parentScriptWidget()), true); + return true; +} + +KVSO_CLASS_FUNCTION(hBox,setMargin) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uMargin; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("margin",KVS_PT_UNSIGNEDINTEGER,0,uMargin) + KVSO_PARAMETERS_END(c) + ((KviTalHBox *)widget())->setMargin(uMargin); + return true; +} + +KVSO_CLASS_FUNCTION(hBox,setSpacing) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uSpacing; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("spacing",KVS_PT_UNSIGNEDINTEGER,0,uSpacing) + KVSO_PARAMETERS_END(c) + ((KviTalHBox *)widget())->setSpacing(uSpacing); + return true; +} + +KVSO_CLASS_FUNCTION(hBox,setStretchFactor) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsObject * pObject; + kvs_hobject_t hObject; + kvs_uint_t uStretch; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETER("stretch",KVS_PT_UNSIGNEDINTEGER,0,uStretch) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + CHECK_HOBJECT_IS_WIDGET(pObject) + if(((KvsObject_widget *)pObject)->widget()->parentWidget() != widget()) + { + c->warning(__tr2qs_ctx("The widget must be a child of this hbox","objects")); + return true; + } + ((KviTalHBox *)widget())->setStretchFactor(((QWidget *)(pObject->object())),uStretch); + return true; +} + +KVSO_CLASS_FUNCTION(hBox,addStretch) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iStretch; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("stretch",KVS_PT_INT,0,iStretch) + KVSO_PARAMETERS_END(c) + ((KviTalHBox *)widget())->addStretch(iStretch); + return true; +} + +KVSO_CLASS_FUNCTION(hBox,setAlignment) +{ + CHECK_INTERNAL_POINTER(widget()) + QStringList alignment; + KviKvsObject * pObject; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETER("alignment",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,alignment) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + CHECK_HOBJECT_IS_WIDGET(pObject) + if(((KvsObject_widget *)pObject)->widget()->parentWidget() != widget()) + { + c->warning(__tr2qs_ctx("The widget must be a child of this hbox","objects")); + return true; + } + int align,sum=0; + for ( QStringList::Iterator it = alignment.begin(); it != alignment.end(); ++it ) + { + + align = 0; + for(unsigned int j = 0; j < align_num; j++) + { + if(KviQString::equalCI((*it), align_tbl[j])) + { + align=align_cod[j]; + break; + } + } + if(align) + sum = sum | align; + else + c->warning(__tr2qs_ctx("Unknown alignment '%Q'","objects"),&(*it)); + + } + ((KviTalHBox *)widget())->setAlignment(((QWidget *)(pObject->object())),(Qt::Alignment)sum); + return true; +} diff --git a/src/modules/objects/KvsObject_hBox.h b/src/modules/objects/KvsObject_hBox.h new file mode 100644 index 000000000..29e9a75c0 --- /dev/null +++ b/src/modules/objects/KvsObject_hBox.h @@ -0,0 +1,49 @@ +#ifndef _CLASS_HBOX_H_ +#define _CLASS_HBOX_H_ +//============================================================================= +// +// File : KvsObject_hBox.h +// Creation date : Wed Mar 01 2005 23:00:01 by Alessandro Carbone & Tonino Imbesi +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2009 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "object_macros.h" +#include "KvsObject_widget.h" + +class KvsObject_hBox : public KvsObject_widget +{ +public: + KVSO_DECLARE_OBJECT(KvsObject_hBox) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool setMargin(KviKvsObjectFunctionCall *c); + bool setSpacing(KviKvsObjectFunctionCall *c); + bool setStretchFactor(KviKvsObjectFunctionCall *c); + bool addStretch(KviKvsObjectFunctionCall *c); + bool setAlignment(KviKvsObjectFunctionCall *c); + + +}; + + +#endif //_CLASS_HBOX_H_ diff --git a/src/modules/objects/KvsObject_http.cpp b/src/modules/objects/KvsObject_http.cpp new file mode 100644 index 000000000..c0adda535 --- /dev/null +++ b/src/modules/objects/KvsObject_http.cpp @@ -0,0 +1,561 @@ +//============================================================================= +// +// File : KvsObject_http.cpp +// Creation date : Fry Sep 5 18:13:45 2008 GMT by Carbone Alesssandro +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2009 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_http.h" + +#include "kvi_debug.h" +#include "KviError.h" +#include "KviLocale.h" + +#include +#include +#include + +#ifndef QT_NO_OPENSSL + #include + + const char * const ssl_errors_tbl[] = { + "NoError", + "UnableToGetIssuerCertificate", + "UnableToDecryptCertificateSignature", + "UnableToDecodeIssuerPublicKey", + "CertificateSignatureFailed", + "CertificateNotYetValid", + "CertificateExpired", + "InvalidNotBeforeField", + "InvalidNotAfterField", + "SelfSignedCertificate", + "SelfSignedCertificateInChain", + "UnableToGetLocalIssuerCertificate", + "UnableToVerifyFirstCertificate", + "CertificateRevoked", + "InvalidCaCertificate", + "PathLengthExceeded", + "InvalidPurpose", + "CertificateUntrusted", + "CertificateRejected", + "SubjectIssuerMismatch", + "AuthorityIssuerSerialNumberMismatch", + "NoPeerCertificate", + "HostNameMismatch", + "UnspecifiedError", + "NoSslSupport" + }; +#endif + +/* + @doc: http + @keyterms: + http object class + @title: + http class + @type: + class + @short: + An implementation of the client side of HTTP protocol. + @inherits: + [class]object[/class] + @description: + This class provides a standard HTTP functionality.[br] + @functions: + !fn: $get(,[]) + Sends a get request for path to the server set by [classfnc]$setHost[/classfnc]. + If local_file is not specified readyRead() signal is emitted every time new content data is available to read. + !fn: $post(,, + Sends a post request for path to the server set by [classfnc]$setHost[/classfnc]. + If local_file is not specified readyRead() signal is emitted every time new content data is available to read. + !fn: $abort() + Aborts the current request and deletes all scheduled requests. + !fn: $setHost(,) + Sets the HTTP server that is used for requests to hostName on port port. + The function does not block: the request is scheduled, and its execution is performed asynchronously. + The function returns a unique identifier which is passed by [classfnc]requestStartedEvent()[/classfnc] and [classfnc]requestFinishedEvent()[/classfnc]. + When the request is started the requestStarted() signal is emitted. When it is finished the requestFinished() signal is emitted. + !fn: $currentId() + Returns the identifier of the HTTP request being executed or 0 if there is no request being executed. + !fn: $setProxy(,,[,]) + Enables HTTP proxy support, using the proxy server host on port port. + Optionals parameters user and password can be provided if the proxy server requires authentication. + !fn: $setUser(,) + This function sets the user name userName and password password for web pages that require authentication. + !fn: $readAll() + Reads all the bytes from the response content and returns them as string. + !fn: $errorString() + Returns a human-readable description of the last error that occurred. + !fn: $ignoreSslErrors() + !fn: $requestFinishedEvent(,) + This event is triggered by KVIrc when the request identified by has finished. + !fn: $requestStartedEvent(,) + This event is triggered by KVIrc when the request identified by has started. + !fn: $responseHeaderReceivedEvent() + This event is triggered by KVIrc when he HTTP header of a server response is available. + The response is passed ad string. + !fn: $doneEvent() + This event is triggered when the last pending request has finished; (it is emitted after the last request's requestFinished() signal). + !fn: $dataReadProgressEvent(,) + This event is triggered when reads data from a HTTP server. + is the amount of data has already arrived and is the total amount of data. + !fn: $dataSendProgressEvent(,) + This event is triggered when sends data to a HTTP server. + is the amount of data has already arrived and is the total amount of data. + !fn: $stateChangedEvent() + This event is triggered by the framework when the state of the connection changes. + !fn: $readyReadEvent() + This event is triggered by the framework when there is new data read and there is not file specified in [classfnc]get[/classfunc] or [classfnc]post[/classfunc]. + You can call [classfnc]readAll[/classfnc] to reads all the bytes from the response data. + !fn: $sslErrorsEvent() + Returns the list of errors that occurred during the SSL handshake. + Unless you call ignoreSslErrors() from within a slot connected to the signal emited by this event, + the framwork will tear down the connection immediately after emitting the signal. + @signals: + !sg: $requestStarted() + This signal is emitted by the default implementation of [classfnc]$requestStartedEvent[/classfnc]. + !sg: $requestFinished() + This signal is emitted by the default implementation of [classfnc]$requestFinishedEvent[/classfnc]. + !sg: $dataSendProgress() + This signal is emitted by the default implementation of [classfnc]$dataSendProgressEvent[/classfnc]. + !sg: $dataReadProgress() + This signal is emitted by the default implementation of [classfnc]$dataReadProgressEvent[/classfnc]. + !sg: $done() + This signal is emitted by the default implementation of [classfnc]$doneEvent[/classfnc]. + !sg: $readyRead() + This signal is emitted by the default implementation of [classfnc]$readyReadEvent[/classfnc]. + !sg: $sslErrors() + This signal is emitted by the default implementation of [classfnc]$sslErrorsEvent[/classfnc]. + !sg: $stateChanged() + This signal is emitted by the default implementation of [classfnc]$stateChangedEvent[/classfnc]. + !sg: $responseHeaderReceived() + This signal is emitted by the default implementation of [classfnc]$responseHeaderReceivedEvent[/classfnc]. +*/ + +KVSO_BEGIN_REGISTERCLASS(KvsObject_http,"http","object") + KVSO_REGISTER_HANDLER(KvsObject_http,"get",functionGet) + KVSO_REGISTER_HANDLER(KvsObject_http,"post",functionPost) + KVSO_REGISTER_HANDLER(KvsObject_http,"abort",functionAbort) + KVSO_REGISTER_HANDLER(KvsObject_http,"setHost",functionSetHost) + KVSO_REGISTER_HANDLER(KvsObject_http,"setProxy",functionSetProxy) + KVSO_REGISTER_HANDLER(KvsObject_http,"currentId",functionCurrentId) + KVSO_REGISTER_HANDLER(KvsObject_http,"setUser",functionSetUser) + KVSO_REGISTER_HANDLER(KvsObject_http,"readAll",functionReadAll) + KVSO_REGISTER_HANDLER(KvsObject_http,"errorString",functionErrorString) + KVSO_REGISTER_HANDLER(KvsObject_http,"setFollowRedirect",functionFollowRedirect) + + // events + KVSO_REGISTER_HANDLER(KvsObject_http,"doneEvent",functionDoneEvent) + KVSO_REGISTER_HANDLER(KvsObject_http,"requestFinishedEvent",functionRequestFinishedEvent) + KVSO_REGISTER_HANDLER(KvsObject_http,"requestStartedEvent",functionRequestStartedEvent) + KVSO_REGISTER_HANDLER(KvsObject_http,"responseHeaderReceivedEvent",functionResponseHeaderReceivedEvent) + KVSO_REGISTER_HANDLER(KvsObject_http,"dataReadProgressEvent",functionDataReadProgressEvent) + KVSO_REGISTER_HANDLER(KvsObject_http,"dataSendProgressEvent",functionDataSendProgressEvent) + KVSO_REGISTER_HANDLER(KvsObject_http,"stateChangedEvent",functionStateChangedEvent) + KVSO_REGISTER_HANDLER(KvsObject_http,"readyReadEvent",functionReadyReadEvent) + #ifndef QT_NO_OPENSSL + KVSO_REGISTER_HANDLER(KvsObject_http,"sslErrorsEvent",functionSslErrorsEvent) + KVSO_REGISTER_HANDLER(KvsObject_http,"ignoreSSlErrors",functionIgnoreSslErrors) + #endif +KVSO_END_REGISTERCLASS(KvsObject_http) + + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_http,KviKvsObject) + m_pHttp = new QHttp(); + m_bAbort=false; + m_bEnableForceRedirect=false; + connect(m_pHttp,SIGNAL(requestFinished(int,bool)),this,SLOT(slotRequestFinished(int,bool))); + connect(m_pHttp,SIGNAL(done(bool)),this,SLOT(slotDone(bool))); + + connect(m_pHttp,SIGNAL(requestStarted(int)),this,SLOT(slotRequestStarted(int))); + connect(m_pHttp,SIGNAL(dataSendProgress(int,int)),this,SLOT(slotDataSendProgress(int,int))); + connect(m_pHttp,SIGNAL(dataReadProgress(int,int)),this,SLOT(slotDataReadProgress(int,int))); + connect(m_pHttp,SIGNAL(responseHeaderReceived ( const QHttpResponseHeader & )),this,SLOT(slotResponseHeaderReceived(const QHttpResponseHeader &))); + connect(m_pHttp,SIGNAL(readyRead ( const QHttpResponseHeader & )),this,SLOT(slotReadyRead(const QHttpResponseHeader &))); + #ifndef QT_NO_OPENSSL + connect(m_pHttp,SIGNAL(sslErrors ( const QList & )),this,SLOT(slotSslErrors(const QList & ))); + #endif + connect(m_pHttp,SIGNAL(stateChanged(int)),this,SLOT(slotStateChanged(int))); + +KVSO_END_CONSTRUCTOR(KvsObject_http) + +KVSO_BEGIN_DESTRUCTOR(KvsObject_http) + QHashIterator t(getDict); + while (t.hasNext()) + { + t.next(); + int key=t.key(); + QFile *pFile=getDict.value(key); + pFile->close(); + delete pFile; + } + getDict.clear(); + delete m_pHttp; + +KVSO_END_DESTRUCTOR(KvsObject_http) +//---------------------- + + +bool KvsObject_http::functionSetHost(KviKvsObjectFunctionCall *c) +{ + CHECK_INTERNAL_POINTER(m_pHttp) + QString szHost; + QString szConnectionType; + kvs_uint_t uRemotePort; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("host",KVS_PT_STRING,0,szHost) + KVSO_PARAMETER("remote_port",KVS_PT_UNSIGNEDINTEGER,KVS_PF_OPTIONAL,uRemotePort) + KVSO_PARAMETERS_END(c) + QUrl url(szHost); + if (!url.isValid()) + { + c->warning(__tr2qs_ctx("Host '%Q' is not a valid url","objects"),&szHost); + return true; + } + if (!szHost.isEmpty() && url.host().isEmpty()) url.setHost(szHost); + if (!uRemotePort) uRemotePort=80; + kvs_uint_t id=0; + QHttp::ConnectionMode mode; + if(url.scheme().toLower()=="https") mode=QHttp::ConnectionModeHttps; + else {mode=QHttp::ConnectionModeHttp;url.setScheme("http");} + if (mode==QHttp::ConnectionModeHttps) uRemotePort=443; + id=m_pHttp->setHost(url.host(), mode, uRemotePort); + c->returnValue()->setInteger(id); + return true; +} +bool KvsObject_http::functionCurrentId(KviKvsObjectFunctionCall *c) +{ + CHECK_INTERNAL_POINTER(m_pHttp) + c->returnValue()->setInteger(m_pHttp->currentId()); + return true; +} +bool KvsObject_http::functionSetUser(KviKvsObjectFunctionCall *c) +{ + CHECK_INTERNAL_POINTER(m_pHttp) + QString szUser; + QString szPass; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("user",KVS_PT_STRING,0,szUser) + KVSO_PARAMETER("password",KVS_PT_STRING,0,szPass) + KVSO_PARAMETERS_END(c) + kvs_int_t id; + id=m_pHttp->setUser(szUser,szPass); + return true; +} +bool KvsObject_http::functionSetProxy(KviKvsObjectFunctionCall *c) +{ + CHECK_INTERNAL_POINTER(m_pHttp) + QString szHost; + QString szUser,szPass; + kvs_uint_t uRemotePort; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("host",KVS_PT_STRING,0,szHost) + KVSO_PARAMETER("remote_port",KVS_PT_UNSIGNEDINTEGER,KVS_PF_OPTIONAL,uRemotePort) + KVSO_PARAMETER("user",KVS_PT_STRING,KVS_PF_OPTIONAL,szUser) + KVSO_PARAMETER("pass",KVS_PT_STRING,KVS_PF_OPTIONAL,szPass) + KVSO_PARAMETERS_END(c) + m_pHttp->setProxy(szHost,uRemotePort,szUser,szPass); + return true; +} + +bool KvsObject_http::functionGet(KviKvsObjectFunctionCall *c) +{ + CHECK_INTERNAL_POINTER(m_pHttp) + QString szPath,szDest; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("remote_path",KVS_PT_STRING,0,szPath) + KVSO_PARAMETER("local_filename",KVS_PT_STRING,KVS_PF_OPTIONAL,szDest) + KVSO_PARAMETERS_END(c) + + QFile * pFile=0; + if (!szDest.isEmpty()) + { + pFile=new QFile(szDest); + if (pFile) + { + pFile->open(QIODevice::WriteOnly); + } else { + c->warning(__tr2qs_ctx("'%Q' is not a valid file path","objects"),&szDest); + c->returnValue()->setInteger(-1); + return true; + } + } + + if (szPath.isEmpty()) szPath="/"; + int id=m_pHttp->get(szPath,pFile); + if (pFile) getDict[id]=pFile; + c->returnValue()->setInteger(id); + return true; +} +bool KvsObject_http::functionPost(KviKvsObjectFunctionCall *c) +{ + CHECK_INTERNAL_POINTER(m_pHttp) + QString szPath,szDest,szData; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("remote_path",KVS_PT_STRING,0,szPath) + KVSO_PARAMETER("post_data",KVS_PT_STRING,0,szData) + KVSO_PARAMETER("local_filename",KVS_PT_STRING,0,szDest) + KVSO_PARAMETERS_END(c) + QFile *pFile=0; + if (!szDest.isEmpty()){ + pFile=new QFile(szDest); + if (pFile){ + pFile->open(QIODevice::WriteOnly); + } + } + if (szPath.isEmpty()) szPath="/"; + int id=m_pHttp->post(szPath,szDest.toAscii(),pFile); + if (pFile) getDict[id]=pFile; + c->returnValue()->setInteger(id); + return true; +} +bool KvsObject_http::functionAbort(KviKvsObjectFunctionCall *c) +{ + CHECK_INTERNAL_POINTER(m_pHttp) + m_bAbort=true; + m_pHttp->abort(); + return true; +} +bool KvsObject_http::functionReadAll(KviKvsObjectFunctionCall *c) +{ + CHECK_INTERNAL_POINTER(m_pHttp) + c->returnValue()->setString(m_pHttp->readAll()); + return true; +} +bool KvsObject_http::functionErrorString(KviKvsObjectFunctionCall *c) +{ + CHECK_INTERNAL_POINTER(m_pHttp) + c->returnValue()->setString(m_pHttp->errorString()); + return true; +} +bool KvsObject_http::functionFollowRedirect(KviKvsObjectFunctionCall *c) +{ + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("enable",KVS_PT_BOOLEAN,0,bEnabled) + KVSO_PARAMETERS_END(c) + m_bEnableForceRedirect=bEnabled; + return true; +} +//signals & slots + +bool KvsObject_http::functionRequestFinishedEvent(KviKvsObjectFunctionCall *c) +{ + emitSignal("requestFinished",c,c->params()); + return true; +} + +void KvsObject_http::slotRequestFinished ( int id, bool error ) +{ + + if (m_bAbort) + { + m_bAbort=false; + QHashIterator t(getDict); + while (t.hasNext()) + { + t.next(); + int key=t.key(); + QFile *pFile=getDict.value(key); + pFile->close(); + delete pFile; + } + getDict.clear(); + return; + } + QFile *pFile=getDict.value(id); + if (pFile) + { + QString name=pFile->fileName(); + pFile->close(); + getDict.remove(id); + int res=m_pHttp->lastResponse().statusCode(); + if ((res==301 || res==302 || res==307) && m_bEnableForceRedirect) + redirect(name,m_pHttp->lastResponse()); + delete pFile; + } + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant((kvs_int_t) id)); + lParams.append(new KviKvsVariant(error)); + callFunction(this,"requestFinishedEvent",0,&lParams); +} + +bool KvsObject_http::functionRequestStartedEvent(KviKvsObjectFunctionCall *c) +{ + emitSignal("requestStarted",c,c->params()); + return true; +} +void KvsObject_http::slotRequestStarted ( int id ) +{ + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant((kvs_int_t) id)); + callFunction(this,"requestStartedEvent",0,&lParams); +} + +void KvsObject_http::slotDataReadProgress ( int done,int total ) +{ + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant((kvs_int_t) done)); + lParams.append(new KviKvsVariant((kvs_int_t) total)); + callFunction(this,"dataReadProgressEvent",0,&lParams); +} +bool KvsObject_http::functionDataReadProgressEvent(KviKvsObjectFunctionCall *c) +{ + emitSignal("dataReadProgress",c,c->params()); + return true; +} +void KvsObject_http::slotDataSendProgress ( int done,int total ) +{ + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant((kvs_int_t) done)); + lParams.append(new KviKvsVariant((kvs_int_t) total)); + callFunction(this,"dataSendProgressEvent",0,&lParams); +} +bool KvsObject_http::functionDataSendProgressEvent(KviKvsObjectFunctionCall *c) +{ + emitSignal("dataSendProgress",c,c->params()); + return true; +} +bool KvsObject_http::functionDoneEvent(KviKvsObjectFunctionCall *c) +{ + emitSignal("done",c,c->params()); + return true; +} +void KvsObject_http::slotDone ( bool error ) +{ + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant(error)); + callFunction(this,"doneEvent",0,&lParams); +} + +bool KvsObject_http::functionResponseHeaderReceivedEvent(KviKvsObjectFunctionCall *c) +{ + emitSignal("responseHeaderReceived",c,c->params()); + return true; +} +bool KvsObject_http::functionReadyReadEvent(KviKvsObjectFunctionCall *c) +{ + emitSignal("readyRead",c,c->params()); + return true; +} +void KvsObject_http::redirect(QString &file,const QHttpResponseHeader &r) +{ + QUrl url(r.value("location")); + m_pHttp->setHost(url.host()); + QFile *pFile=0; + pFile=new QFile(file); + pFile->open(QIODevice::WriteOnly); + int id=m_pHttp->get(url.path(),pFile); + getDict[id]=pFile; +} + +void KvsObject_http::slotResponseHeaderReceived(const QHttpResponseHeader &r) +{ + QString szResponse; + switch (r.statusCode()) { + case 200: szResponse="Ok" ;break; + case 301: szResponse="Moved Permanently" ;break; + case 302: szResponse="Found" ;break; + case 303: szResponse="See Other" ;break; + case 307: szResponse="Temporary Redirect" ;break; + default: szResponse=r.reasonPhrase(); + m_bAbort=true; + } + if (r.statusCode()==400) + { + m_bAbort=true; + m_pHttp->abort(); + } + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant(szResponse)); + callFunction(this,"responseHeaderReceivedEvent",0,&lParams); + +} +void KvsObject_http::slotReadyRead(const QHttpResponseHeader &r) +{ + QString szResponse; + switch (r.statusCode()) { + case 200: szResponse="Ok" ;break; + case 301: szResponse="Moved Permanently" ;break; + case 302: szResponse="Found" ;break; + case 303: szResponse="See Other" ;break; + case 307: szResponse="Temporary Redirect" ;break; + default: szResponse=r.reasonPhrase(); + m_bAbort=true; + } + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant(szResponse)); + callFunction(this,"readyreadEvent",0,&lParams); +} + + + + +void KvsObject_http::slotStateChanged ( int state) +{ + QString szState=""; + if (state==QHttp::Unconnected) szState="Unconnected"; + else if (state==QHttp::HostLookup) szState="HostLookup"; + else if (state==QHttp::Connecting) szState="Connecting"; + else if (state==QHttp::Connected) szState="Connected"; + else if (state==QHttp::Sending) szState="Sending"; + else if (state==QHttp::Reading) szState="Reading"; + + else if (state==QHttp::Closing) szState="Closing"; + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant(szState)); + callFunction(this,"stateChangedEvent",0,&lParams); +} +bool KvsObject_http::functionStateChangedEvent(KviKvsObjectFunctionCall *c) +{ + emitSignal("stateChanged",c,c->params()); + return true; +} + +#ifndef QT_NO_OPENSSL + +bool KvsObject_http::functionIgnoreSslErrors(KviKvsObjectFunctionCall *) +{ + if (m_pHttp) m_pHttp->ignoreSslErrors(); + return true; +} +void KvsObject_http::slotSslErrors(QList sslerrors) +{ + KviKvsArray *pArray=0; + pArray=new KviKvsArray(); + for(int i=0;iset(i,new KviKvsVariant(ssl_errors_tbl[sslerrors.at(i).error()])); + } + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant(pArray)); + callFunction(this,"sslErrorEvent",0,&lParams); + } + +bool KvsObject_http::functionSslErrorsEvent(KviKvsObjectFunctionCall *c) +{ + + emitSignal("sslErrors",c,c->params()); + return true; +} +#endif +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_http.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/objects/KvsObject_http.h b/src/modules/objects/KvsObject_http.h new file mode 100644 index 000000000..1ef5ef592 --- /dev/null +++ b/src/modules/objects/KvsObject_http.h @@ -0,0 +1,89 @@ +#ifndef _CLASS_HTTP_H_ +#define _CLASS_HTTP_H_ +//============================================================================= +// +// File : KvsObject_http.h +// Creation date : Fry Sep 5 18:13:45 2008 GMT by Carbone Alesssandro +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + + + +//=============================================================== +#include "object_macros.h" +#include +#include +#include +#include + +class KvsObject_http : public KviKvsObject +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_http) +protected: + QHttp *m_pHttp; + QHash getDict; + bool m_bAbort; + bool m_bEnableForceRedirect; +protected: + bool functionSetHost(KviKvsObjectFunctionCall *c); + bool functionGet(KviKvsObjectFunctionCall *c); + bool functionSetUser(KviKvsObjectFunctionCall *c); + bool functionSetProxy(KviKvsObjectFunctionCall *c); + bool functionRequestFinishedEvent(KviKvsObjectFunctionCall *c); + bool functionRequestStartedEvent(KviKvsObjectFunctionCall *c); + bool functionDataReadProgressEvent(KviKvsObjectFunctionCall *c); + bool functionDataSendProgressEvent(KviKvsObjectFunctionCall *c); + bool functionResponseHeaderReceivedEvent(KviKvsObjectFunctionCall *c); + bool functionAbort(KviKvsObjectFunctionCall *c); + bool functionDoneEvent(KviKvsObjectFunctionCall *c); + bool functionStateChangedEvent(KviKvsObjectFunctionCall *c); + bool functionReadAll(KviKvsObjectFunctionCall *c); + bool functionReadyReadEvent(KviKvsObjectFunctionCall *c); + bool functionErrorString(KviKvsObjectFunctionCall *c); + bool functionPost(KviKvsObjectFunctionCall *c); + bool functionFollowRedirect(KviKvsObjectFunctionCall *c); + bool functionCurrentId(KviKvsObjectFunctionCall *c); + void redirect(QString &file,const QHttpResponseHeader &r); + + #ifndef QT_NO_OPENSSL + bool functionIgnoreSslErrors(KviKvsObjectFunctionCall *c); + bool functionSslErrorsEvent(KviKvsObjectFunctionCall *c); + #endif + +protected slots: + void slotRequestFinished ( int id, bool error ); + void slotDone (bool error ); + void slotRequestStarted ( int id ); + void slotDataSendProgress ( int done, int total ); + void slotDataReadProgress ( int done, int total ); + #ifndef QT_NO_OPENSSL + void slotSslErrors(QList); + #endif + void slotResponseHeaderReceived(const QHttpResponseHeader &r); + void slotReadyRead(const QHttpResponseHeader &r); + void slotStateChanged ( int state); + + + +}; +#endif //_CLASS_HTTP_H_ diff --git a/src/modules/objects/KvsObject_label.cpp b/src/modules/objects/KvsObject_label.cpp new file mode 100644 index 000000000..08cb4ffa1 --- /dev/null +++ b/src/modules/objects/KvsObject_label.cpp @@ -0,0 +1,361 @@ +//============================================================================= +// +// File : KvsObject_label.cpp +// Creation date : Mon Sep 18 14:21:48 CEST 2000 by Krzysztof Godlewski +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000 Krzysztof Godlewski +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviError.h" +#include "kvi_debug.h" +#include "KvsObject_label.h" +#include "KviLocale.h" +#include "KviIconManager.h" + +#include +#include +#include +#include + + + +// Tables used in $setAlignment & $alignment +const char * const align_tbl[] = { + "Left", + "Right", + "HCenter", + "VCenter", + "Center", + "Top", + "Bottom", + "WordBreak" +}; + +const int align_cod[] = { + Qt::AlignLeft, + Qt::AlignRight, + Qt::AlignHCenter, + Qt::AlignVCenter, + Qt::AlignCenter, + Qt::AlignTop, + Qt::AlignBottom, + Qt::AlignJustify, +}; + +#define align_num (sizeof(align_tbl) / sizeof(align_tbl[0])) + +// used in $frameStyle & $setFrameStyle +const char * const frame_tbl[] = { + "NoFrame", + "Box", + "Panel", + "WinPanel", + "Hline", + // shadow styles + "Plain", + "Raised", + "Sunken" +}; + +const int frame_cod[] = { + QFrame::NoFrame, + QFrame::Box, + QFrame::Panel, + QFrame::WinPanel, + QFrame::HLine, + QFrame::Plain, + QFrame::Raised, + QFrame::Sunken +}; + +#define frame_num (sizeof(frame_tbl) / sizeof(frame_tbl[0])) + + +/* + @doc: label + @keyterms: + label object class, show image + @title: + label class + @type: + class + @short: + Displays text or an image + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + This widget can be used to display a text or an image. It can + have different frame styles and text/image alignment. + @functions: + !fn: $setText() + Sets the text to be displayed by the label. + The text can contain limited html tags. + See also [classfnc]$text[/classfnc](). + !fn: $text() + Returns the text currently displayed by the label. + See also [classfnc]$setText[/classfnc](). + !fn: $margin() + Returns current value of margin for this label (default is 0). + See also [classfnc]$setMargin[/classfnc](). + !fn: $setMargin() + Sets margin width / height to . + See also [classfnc]$margin[/classfnc](). + !fn: $alignment() + Returns a string containing alignment flags that are set for + this label. The flags are separated by commas. An example output + could look like this:[br] + [pre]Bottom, Right[/pre][br] + See [classfnc]$setAlignment[/classfnc]() for explanation of all + alignment flags. + !fn: $setAlignment(, , ...) + This function sets alignment flags, given as parameters, for + this label. Valid flags are: + [pre] + Right - Text is aligned to right border[br] + Left - Text is aligned to left border[br] + Top - Text is aligned to the top border[br] + Bottom - Text is aligned to the bottom border[br] + HCenter - Text is horizontally centered[br] + VCenter - Text is vertically centered[br] + Center - Equals HCenter + VCenter[br] + WordBreak - Enables automatic word breaking[br] + [/pre] + It is obvious that you can not set for example [i]Right[/i] + and [i]Left[/i] simoultaneously - this will [b]NOT[/b] + result in an error message - this will simply not work :) + !fn: $clear() + Clears the label. Equal to calling + [classfnc]$setText[/classfnc]("") + !fn: $frameStyle() + Returns a string containing this label's frame-style flags, + separated with commas. Output from this function could look like + this: + [pre]Panel, Raised[/pre] + See [classfnc]$setFrameStyle[/classfnc]() for a list of all + frame-style flags and their explenation. + !fn: $setFrameStyle(, , ...) + Sets the frame-style flags to the ones passed as arguments. + The flags can either decide of the shape or shadow of the + label's frame. Valid shape flags are:[br] + [pre] + NoFrame - draw no frame. You shouldn't specify a shadow when + using this.[br] + Box - draws a rectangular box. Its borders can be + [i]Raised[/i] or [i]Sunken[/i][br] + Panel - draws a rectangular panel which can be + [i]Raised[/i] or [i]Sunken[/i][br] + WinPanel - similar to [i]Panel[/i], but is more in Win95 + style[br] + Hline - draws a horizontal line that frames nothing (useful as separator) + [/pre] + Valid shadow flags are:[br] + [pre] + Plain - no 3D effect (draws using foreground color)[br] + Raised - makes the label look like it was raised above the + parent widget[br] + Sunken - makes the label look like it was "pushed" inside + the parent widget[br] + [/pre] + !fn: $setImage() + Sets the image to be displayed on this label. + Giving empty argument clears the pixmap[br] + See the [doc:image_id]image identifier[/doc] documentation for + the explaination of the parameter. + +*/ + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_label,"label","widget") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_label,setText) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_label,text) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_label,margin) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_label,setMargin) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_label,alignment) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_label,setAlignment) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_label,clear) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_label,frameStyle) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_label,setFrameStyle) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_label,setImage) +KVSO_END_REGISTERCLASS(KvsObject_label) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_label,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_label) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_label) + +KVSO_END_CONSTRUCTOR(KvsObject_label) + +bool KvsObject_label::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + SET_OBJECT(QLabel) + ((QLabel *)widget())->setWordWrap(true); + return true; +} + +KVSO_CLASS_FUNCTION(label,setText) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETERS_END(c) + ((QLabel *)widget())->setText(szText); + return true; +} + +KVSO_CLASS_FUNCTION(label,text) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setString(((QLabel *)widget())->text()); + return true; +} + +KVSO_CLASS_FUNCTION(label,setMargin) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t iMargin; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("margin",KVS_PT_UNSIGNEDINTEGER,0,iMargin) + KVSO_PARAMETERS_END(c) + ((QLabel *)widget())->setMargin(iMargin); + return true; +} +KVSO_CLASS_FUNCTION(label,margin) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QLabel *)widget())->margin()); + return true; +} + +KVSO_CLASS_FUNCTION(label,setAlignment) +{ + CHECK_INTERNAL_POINTER(widget()) + QStringList alignment; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("alignment",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,alignment) + KVSO_PARAMETERS_END(c) + int align,sum=0; + for ( QStringList::Iterator it = alignment.begin(); it != alignment.end(); ++it ) + { + + align = 0; + for(unsigned int j = 0; j < align_num; j++) + { + if(KviQString::equalCI((*it), align_tbl[j])) + { + align=align_cod[j]; + break; + } + } + if(align) + sum = sum | align; + else + c->warning(__tr2qs_ctx("Unknown alignment '%Q'","objects"),&(*it)); + + } + ((QLabel *)widget())->setAlignment((Qt::Alignment)sum); + return true; +} + +KVSO_CLASS_FUNCTION(label,alignment) +{ + CHECK_INTERNAL_POINTER(widget()) + int mode = ((QLabel *)widget())->alignment(); + QString szAlignment=""; + for(unsigned int i = 0; i < align_num; i++) + { + if(mode == align_cod[i]) + { + szAlignment=align_tbl[i]; + break; + } + } + c->returnValue()->setString(szAlignment); + return true; +} + +KVSO_CLASS_FUNCTION(label,clear) +{ + CHECK_INTERNAL_POINTER(widget()) + ((QLabel *)widget())->clear(); + return true; +} + +KVSO_CLASS_FUNCTION(label,setFrameStyle) +{ + CHECK_INTERNAL_POINTER(widget()) + QStringList style; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("style",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,style) + KVSO_PARAMETERS_END(c) + if (!widget()) return true; + int framestyle,sum=0; + for ( QStringList::Iterator it = style.begin(); it != style.end(); ++it ) + { + framestyle = 0; + for(unsigned int j = 0; j < align_num; j++) + { + if(KviQString::equalCI((*it), frame_tbl[j])) + { + framestyle=frame_cod[j]; + break; + } + } + if(framestyle) + sum = sum | framestyle; + else + c->warning(__tr2qs_ctx("Unknown style '%Q'","objects"),&(*it)); + + } + ((QLabel *)widget())->setFrameStyle(sum); + return true; +} + +KVSO_CLASS_FUNCTION(label,frameStyle) +{ + CHECK_INTERNAL_POINTER(widget()) + int mode = ((QLabel *)widget())->frameStyle(); + QString szStyle=""; + for(unsigned int i = 0; i < frame_num; i++) + { + if(mode == frame_cod[i]) + { + szStyle=frame_tbl[i]; + break; + } + } + c->returnValue()->setString(szStyle); + return true; +} + +KVSO_CLASS_FUNCTION(label,setImage) +{ + CHECK_INTERNAL_POINTER(widget()) + QString icon; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("icon",KVS_PT_STRING,0,icon) + KVSO_PARAMETERS_END(c) + QPixmap * pix = g_pIconManager->getImage(icon); + if(pix) ((QLabel *)widget())->setPixmap(*pix); + return true; +} diff --git a/src/modules/objects/KvsObject_label.h b/src/modules/objects/KvsObject_label.h new file mode 100644 index 000000000..f043f126b --- /dev/null +++ b/src/modules/objects/KvsObject_label.h @@ -0,0 +1,53 @@ +#ifndef _CLASS_LABEL_H_ +#define _CLASS_LABEL_H_ +//============================================================================= +// +// File : KvsObject_label.h +// Creation date : Mon Sep 18 14:21:48 CEST 2000 by Krzysztof Godlewski +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000 Krzysztof Godlewski +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include "KvsObject_widget.h" +#include "object_macros.h" + +class KvsObject_label : public KvsObject_widget +{ +public: + KVSO_DECLARE_OBJECT(KvsObject_label) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool setTitle(KviKvsObjectFunctionCall *c); + bool setText(KviKvsObjectFunctionCall *c); + bool text(KviKvsObjectFunctionCall *c); + bool margin(KviKvsObjectFunctionCall *c); + bool setMargin(KviKvsObjectFunctionCall *c); + bool alignment(KviKvsObjectFunctionCall *c); + bool setAlignment(KviKvsObjectFunctionCall *c); + bool clear(KviKvsObjectFunctionCall *c); + bool frameStyle(KviKvsObjectFunctionCall *c); + bool setFrameStyle(KviKvsObjectFunctionCall *c); + bool setImage(KviKvsObjectFunctionCall *c); +}; +#endif // !_CLASS_LABEL_H_ diff --git a/src/modules/objects/KvsObject_layout.cpp b/src/modules/objects/KvsObject_layout.cpp new file mode 100644 index 000000000..8d923da2e --- /dev/null +++ b/src/modules/objects/KvsObject_layout.cpp @@ -0,0 +1,317 @@ +//============================================================================= +// +// File : KvsObject_layout.cpp +// Creation date : Fri Now 22 2002 00:50:01 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#define _KVI_DEBUG_CHECK_RANGE_ +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KvsObject_layout.h" + +#include + + + +// Tables used in $setAlignment & $alignment +const char * const align_tbl[] = { + "Left", + "Right", + "HCenter", + "VCenter", + "Center", + "Top", + "Bottom", + }; + + + +const int align_cod[] = { + Qt::AlignLeft, + Qt::AlignRight, + Qt::AlignHCenter, + Qt::AlignVCenter, + Qt::AlignCenter, + Qt::AlignTop, + Qt::AlignBottom, + }; +#define align_num (sizeof(align_tbl) / sizeof(align_tbl[0])) +/* + @doc: layout + @keyterms: + layout object class, child widgets + @title: + layout class + @type: + class + @short: + Manages child widget geometry + @inherits: + [class]object[/class] + @description: + The layout is a geometry management tool for child widgets. + You create a layout, give it some widgets to manage and it will layout them + automatically.[br] + The parent of the layout must be the widget for which child widget geometries have to be managed. + A layout is a grid of NxM cells in which you insert child widgets with [classfnc:layout]$addWidget[/classfnc]().[br] + Widgets that must span multiple cells can be added to the layout with [classfnc:layout]$addMultiCellWidget[/classfnc]().[br] + @functions: + !fn: $addWidget(,,) + Adds a widget to this layout placing it at position , in the grid + !fn: $addMultiCellWidget(,,,,) + Adds a widget to this layout spanning multiple grid cells + !fn: $setRowStretch(,) + Sets the stretch value for a particular row of this layout. The + must be a positive integer. The rows with bigger stretch values will take more space + in the layout. + !fn: $setColumnStretch(,) + Sets the stretch value for a particular column in this layout. The + must be a positive integer. The rows with bigger stretch values will take more space + in the layout. + !fn: $addRowSpacing(,) + Sets the minimum height of the specified to which must be a positive integer + !fn: $addColSpacing(,) + Sets the minimum width of the specigfied to which must be a positive integer + !fn: $setSpacing() + Sets the default spacing of the widgets in pixels + !fn: $setMargin() + Sets the dimension of the layout margin : the distance from the border to the outermost child widget edges. + !fn: $setAlignment(, , ...) + Sets the alignment for widget w to flags, given as parameters. + Valid flags are:Right,Left,Top,Bottom,HCenter,VCenter,Center + !fn: $setResizeMode() + Sets the resize mode of the parent widget in relation to this layout. + can be one of:[br] + -Auto: this is the default[br] + -Fixed: the parent widget of this layout is resized to the "sizeHint" value and it cannot be resized by the user.[br] + -Minimum: the minimum size of the parent widget of this layout is set to minimumSize() and it cannot be smaller[br] + -FreeResize: the parent widget of this layout is not constrained at all[br] +*/ + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_layout,"layout","object") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_layout,addWidget) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_layout,addMultiCellWidget) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_layout,setRowStretch) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_layout,setColumnStretch) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_layout,addRowSpacing) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_layout,addColSpacing) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_layout,setMargin) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_layout,setSpacing) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_layout,setResizeMode) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_layout,setAlignment ) +KVSO_END_REGISTERCLASS(KvsObject_layout) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_layout,KviKvsObject) + +KVSO_END_CONSTRUCTOR(KvsObject_layout) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_layout) + +KVSO_END_CONSTRUCTOR(KvsObject_layout) + +bool KvsObject_layout::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *) +{ + QWidget * w = parentScriptWidget(); + + if(!w) + { + pContext->warning(__tr2qs_ctx("The parent of a layout must be a widget!","objects")); + return false; + } + // If there already is a layout manager installed on this widget, QWidget won't let you install another. + if(w->layout()) delete w->layout(); + setObject(new QGridLayout(w)); + ((QGridLayout *)object())->setVerticalSpacing(0); + ((QGridLayout *)object())->setHorizontalSpacing(0); + setObjectName(getName()); + return true; +} + +KVSO_CLASS_FUNCTION(layout,addWidget) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsObject * pObject; + kvs_hobject_t hObject; + kvs_uint_t uCol,uRow; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) + KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + CHECK_HOBJECT_IS_WIDGET(pObject) + ((QGridLayout *)object())->addWidget(((QWidget *)(pObject->object())),uRow,uCol); + return true; +} + +KVSO_CLASS_FUNCTION(layout,addMultiCellWidget) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsObject * pObject; + kvs_hobject_t hObject; + kvs_uint_t uStartCol,uStartRow,uEndCol,uEndRow; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETER("start_row",KVS_PT_UNSIGNEDINTEGER,0,uStartRow) + KVSO_PARAMETER("end_row",KVS_PT_UNSIGNEDINTEGER,0,uEndRow) + KVSO_PARAMETER("start_column",KVS_PT_UNSIGNEDINTEGER,0,uStartCol) + KVSO_PARAMETER("end_column",KVS_PT_UNSIGNEDINTEGER,0,uEndCol) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + CHECK_HOBJECT_IS_WIDGET(pObject) + // { addWidget(w, fromRow, fromCol, (toRow < 0) ? -1 : toRow - fromRow + 1, (toCol < 0) ? -1 : toCol - fromCol + 1, _align); } + ((QGridLayout *)object())->addWidget(((QWidget *)(pObject->object())),uStartRow, uStartCol, uEndRow - uStartRow + 1, uEndCol - uStartCol + 1); + return true; +} + +KVSO_CLASS_FUNCTION(layout,setRowStretch) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uRow,uStretch; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) + KVSO_PARAMETER("stretch",KVS_PT_UNSIGNEDINTEGER,0,uStretch) + KVSO_PARAMETERS_END(c) + ((QGridLayout *)object())->setRowStretch(uRow,uStretch); + return true; +} + +KVSO_CLASS_FUNCTION(layout,setColumnStretch) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uCol,uStretch; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETER("stretch",KVS_PT_UNSIGNEDINTEGER,0,uStretch) + KVSO_PARAMETERS_END(c) + ((QGridLayout *)object())->setColumnStretch(uCol,uStretch); + return true; +} + +KVSO_CLASS_FUNCTION(layout,setMargin) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uMargin; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("margin",KVS_PT_UNSIGNEDINTEGER,0,uMargin) + KVSO_PARAMETERS_END(c) + ((QGridLayout *)object())->setMargin(uMargin); + return true; +} + +KVSO_CLASS_FUNCTION(layout,setSpacing) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uSpacing; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("spacing",KVS_PT_UNSIGNEDINTEGER,0,uSpacing) + KVSO_PARAMETERS_END(c) + ((QGridLayout *)object())->setSpacing(uSpacing); + return true; +} + +KVSO_CLASS_FUNCTION(layout,addRowSpacing) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uSpacing,uRow; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) + KVSO_PARAMETER("spacing",KVS_PT_UNSIGNEDINTEGER,0,uSpacing) + KVSO_PARAMETERS_END(c) + //((QGridLayout *)object())->addRowSpacing(uRow,uSpacing); + ((QGridLayout *)object())->addItem(new QSpacerItem(0, uSpacing), uRow, 0); + return true; +} + +KVSO_CLASS_FUNCTION(layout,addColSpacing) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uSpacing,uCol; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETER("spacing",KVS_PT_UNSIGNEDINTEGER,0,uSpacing) + KVSO_PARAMETERS_END(c) + ((QGridLayout *)object())->addItem(new QSpacerItem(uSpacing,0), 0, uCol); + return true; +} + +KVSO_CLASS_FUNCTION(layout,setResizeMode) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szMode; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("resize_mode",KVS_PT_STRING,0,szMode) + KVSO_PARAMETERS_END(c) + QLayout::SizeConstraint r = QLayout::SetDefaultConstraint; + if(KviQString::equalCI(szMode,"FreeResize")) r = QLayout::SetNoConstraint; + else if(KviQString::equalCI(szMode,"Minimum")) r = QLayout::SetMinimumSize; + else if(KviQString::equalCI(szMode,"Fixed"))r = QLayout::SetFixedSize; + else c->warning(__tr2qs_ctx("Invalid resize mode defaulting to Auto","objects")); + ((QGridLayout *)object())->setSizeConstraint(r); + return true; + +} + +KVSO_CLASS_FUNCTION(layout,setAlignment) +{ + CHECK_INTERNAL_POINTER(widget()) + QStringList alignment; + KviKvsObject * pObject; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETER("alignment",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,alignment) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + CHECK_HOBJECT_IS_WIDGET(pObject) + int index=((QGridLayout *)widget())->indexOf(((QWidget *)(pObject->object()))); + if(index ==-1) + { + c->warning(__tr2qs_ctx("The widget must be a child of this layout","objects")); + return true; + } + + int align,sum=0; + for ( QStringList::Iterator it = alignment.begin(); it != alignment.end(); ++it ) + { + align = 0; + for(unsigned int j = 0; j < align_num; j++) + { + if(KviQString::equalCI((*it), align_tbl[j])) + { + align=align_cod[j]; + break; + } + } + if(align) + sum = sum | align; + else + c->warning(__tr2qs_ctx("Unknown alignment: '%Q'","objects"),&(*it)); + + } + if (widget()) ((QGridLayout *)widget())->setAlignment(((QWidget *)(pObject->object())),(Qt::Alignment)sum); + return true; +} +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_layout.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/objects/KvsObject_layout.h b/src/modules/objects/KvsObject_layout.h new file mode 100644 index 000000000..65580e99e --- /dev/null +++ b/src/modules/objects/KvsObject_layout.h @@ -0,0 +1,53 @@ +#ifndef _CLASS_LAYOUT_H_ +#define _CLASS_LAYOUT_H_ +//============================================================================= +// +// File : KvsObject_layout.h +// Creation date : Fri Now 22 2002 00:50:01 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "object_macros.h" + +class KvsObject_layout : public KviKvsObject +{ +public: + KVSO_DECLARE_OBJECT(KvsObject_layout) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool addWidget(KviKvsObjectFunctionCall *c); + bool addMultiCellWidget(KviKvsObjectFunctionCall *c); + bool setRowStretch(KviKvsObjectFunctionCall *c); + bool setColumnStretch(KviKvsObjectFunctionCall *c); + bool setMargin(KviKvsObjectFunctionCall *c); + bool setSpacing(KviKvsObjectFunctionCall *c); + bool addRowSpacing(KviKvsObjectFunctionCall *c); + bool addColSpacing(KviKvsObjectFunctionCall *c); + bool setResizeMode(KviKvsObjectFunctionCall *c); + bool setAlignment(KviKvsObjectFunctionCall *c); + + +}; + + +#endif //_CLASS_LAYOUT_H_ diff --git a/src/modules/objects/KvsObject_lcd.cpp b/src/modules/objects/KvsObject_lcd.cpp new file mode 100644 index 000000000..ab4664bdc --- /dev/null +++ b/src/modules/objects/KvsObject_lcd.cpp @@ -0,0 +1,191 @@ +//============================================================================= +// +// File : KvsObject_lcd.cpp +// Creation date : Mon Gen 27 14:30:48 CEST 2005 by Tonino Imbesi(Grifisx) +// and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_lcd.h" +#include "KviError.h" +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KviIconManager.h" + +#include + +/* + @doc: lcdnumber + @keyterms: + lcdnumber object class, lcd + @title: + lcdnumber class + @type: + class + @short: + The lcdNumber widget displays a number with LCD-like digits. + @inherits: + + @description: + It can display a number in just about any size. It can display decimal, + hexadecimal, octal or binary numbers. + @functions: + !fn: $displayStr() + Displays the number represented by the string s. + !fn: $displayInt() + Sets the displayed value rounded to the nearest integer to number. + !fn: $displayDouble() + Sets the displayed value to number (double). + !fn: $setMode() + Sets the current display mode (number base): valid mode are HEX,BIN,OCT,DEC. + !fn: $setSegmentStyles() + Sets the style of the lcdnumber, valid styles are: Outline,Filled,Flat. + !fn: $setNumDigits() + Sets the lcd number value. + !fn: $checkOverflow() + Returns TRUE if num is too big to be displayed in its entirety; + otherwise returns FALSE. + !fn: $setSmallDecimalPoint() + Sets the the decimal point style, valid bool values are 1 or 0. + !fn: $checkOverflow() + Returns 1 (TRUE) if num is too big to be displayed in its entirety; otherwise returns 0 (FALSE). +*/ + +KVSO_BEGIN_REGISTERCLASS(KvsObject_lcd,"lcdnumber","widget") + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lcd,displayStr) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lcd,displayInt) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lcd,displayDouble) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lcd,setMode) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lcd,setSegmentStyle) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lcd,setNumDigits) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lcd,setSmallDecimalPoint) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lcd,checkOverflow) +KVSO_END_REGISTERCLASS(KvsObject_lcd) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_lcd,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_lcd) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_lcd) + +KVSO_END_CONSTRUCTOR(KvsObject_lcd) + +bool KvsObject_lcd::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + SET_OBJECT(QLCDNumber) + return true; +} + +KVSO_CLASS_FUNCTION(lcd,displayInt) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iDigit; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("number",KVS_PT_INT,0,iDigit) + KVSO_PARAMETERS_END(c) + ((QLCDNumber *)widget())->display((int)iDigit); + return true; +} + +KVSO_CLASS_FUNCTION(lcd,displayStr) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("number",KVS_PT_STRING,0,szText) + KVSO_PARAMETERS_END(c) + ((QLCDNumber *)widget())->display(szText); + return true; +} + +KVSO_CLASS_FUNCTION(lcd,displayDouble) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_real_t dDigit; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("number",KVS_PT_DOUBLE,0,dDigit) + KVSO_PARAMETERS_END(c) + ((QLCDNumber *)widget())->display(dDigit); + return true; +} + +KVSO_CLASS_FUNCTION(lcd,setMode) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szMode; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("mode",KVS_PT_STRING,0,szMode) + KVSO_PARAMETERS_END(c) + if(KviQString::equalCI(szMode, "HEX")) ((QLCDNumber *)widget())->setHexMode(); + else if(KviQString::equalCI(szMode, "DEC")) ((QLCDNumber *)widget())->setDecMode(); + else if(KviQString::equalCI(szMode, "BIN")) ((QLCDNumber *)widget())->setBinMode(); + else if(KviQString::equalCI(szMode, "OCT")) ((QLCDNumber *)widget())->setOctMode(); + else c->warning( __tr2qs_ctx("Unknown mode '%Q'","objects"),&szMode); + return true; +} + +KVSO_CLASS_FUNCTION(lcd,setSegmentStyle) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szStyle; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("style",KVS_PT_STRING,0,szStyle) + KVSO_PARAMETERS_END(c) + if(KviQString::equalCI(szStyle, "Outline")) ((QLCDNumber *)widget())->setSegmentStyle(QLCDNumber::Outline); + else if(KviQString::equalCI(szStyle, "Filled")) ((QLCDNumber *)widget())->setSegmentStyle(QLCDNumber::Filled); + else if(KviQString::equalCI(szStyle, "Flat")) ((QLCDNumber *)widget())->setSegmentStyle(QLCDNumber::Flat); + else c->warning( __tr2qs_ctx("Unknown segment style '%Q'","objects"),&szStyle); + return true; +} + +KVSO_CLASS_FUNCTION(lcd,setNumDigits) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_real_t digit; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("digit",KVS_PT_DOUBLE,0,digit) + KVSO_PARAMETERS_END(c) + ((QLCDNumber *)widget())->setNumDigits((int)digit); + return true; +} + +KVSO_CLASS_FUNCTION(lcd,setSmallDecimalPoint) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bFlag; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bflag",KVS_PT_BOOLEAN,0,bFlag) + KVSO_PARAMETERS_END(c) + ((QLCDNumber *)widget())->setSmallDecimalPoint(bFlag); + return true; +} + +KVSO_CLASS_FUNCTION(lcd,checkOverflow) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_real_t iDigit; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("digit",KVS_PT_DOUBLE,0,iDigit) + KVSO_PARAMETERS_END(c) + c->returnValue()->setBoolean(((QLCDNumber *)widget())->checkOverflow(iDigit)); + return true; +} diff --git a/src/modules/objects/KvsObject_lcd.h b/src/modules/objects/KvsObject_lcd.h new file mode 100644 index 000000000..77c1fdc38 --- /dev/null +++ b/src/modules/objects/KvsObject_lcd.h @@ -0,0 +1,52 @@ +#ifndef _CLASS_LCD_H_ +#define _CLASS_LCD_H_ +//============================================================================= +// +// File : KvsObject_lcd.h +// Creation date : Mon Gen 27 14:30:48 CEST 2005 by Tonino Imbesi(Grifisx) +// and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + + +#include "KvsObject_widget.h" + + +class KvsObject_lcd : public KvsObject_widget +{ +public: + KVSO_DECLARE_OBJECT(KvsObject_lcd) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool displayStr(KviKvsObjectFunctionCall *c); + bool setMode(KviKvsObjectFunctionCall *c); + bool setSegmentStyle(KviKvsObjectFunctionCall *c); + bool setNumDigits(KviKvsObjectFunctionCall *c); + bool setSmallDecimalPoint(KviKvsObjectFunctionCall *c); + bool checkOverflow(KviKvsObjectFunctionCall *c); + bool displayInt(KviKvsObjectFunctionCall *c); + bool displayDouble(KviKvsObjectFunctionCall *c); +}; + +#endif // !_CLASS_LCD_H_ diff --git a/src/modules/objects/KvsObject_lineEdit.cpp b/src/modules/objects/KvsObject_lineEdit.cpp new file mode 100644 index 000000000..be41500da --- /dev/null +++ b/src/modules/objects/KvsObject_lineEdit.cpp @@ -0,0 +1,543 @@ +//============================================================================= +// +// File : KvsObject_lineEdit.cpp +// Creation date : Wed 20 Sep 2000 04:34:40 CEST by Krzysztof Godlewski +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000 Krzysztof Godlewski +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviError.h" +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KvsObject_lineEdit.h" +#include +#include +#include +static const char * mode_tbl[] = { + "Normal", + "NoEcho", + "Password" + }; + +static const int mode_cod[] = { + QLineEdit::Normal, + QLineEdit::NoEcho, + QLineEdit::Password + }; + +#define mode_num (sizeof(mode_tbl) / sizeof(mode_tbl[0])) + + +/* + @doc: lineedit + @keyterms: + lineedit object class, line editor, input + @title: + lineedit class + @type: + class + @short: + Simple line editor for inputting short text + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + This is a simple, one-line editor usually used for inputting + short text like names, phone numbers etc. It can display text + in three echo modes (see [classfnc]$setEchoMode[/classfnc]() + for details). + @functions: + !fn: $text() + Returns text contained by the widget.[br] + See also [classfnc]$setText[/classfnc](). + !fn: $setText() + Sets editor text to .[br] + See also [classfnc]$text[/classfnc](). + !fn: $setEchoMode() + Sets the line edit's echo mode. Possible value are:[br] + -Normal: display chars as they entered[br] + -Noecho : do not display anything[br] + -Password : display asterisks instead of the characters actually entered[br] + See also [classfnc]$echoMode[/classfnc](). + !fn: $echoMode() + Return the line edit's echo mode. + See also [classfnc]$setEchoMode[/classfnc](). + !fn: $maxLength() + Returns the current maximum length of the text that can be typed + in the editor.[br] + See also [classfnc]$setMaxLength[/classfnc](). + !fn: $setMaxLength() + Sets maximum length of the text that can be typed in the + editor.[br] + See also [classfnc]$maxLength[/classfnc](). + !fn: $frame() + Returns '1' if the editor is drawn inside a frame, which is 2 + pixels wide, '0' otherwise.[br] + See also [classfnc]$setFrame[/classfnc](). + !fn: $setFrame() + Sets editor frame drawing to .[br] + See also [classfnc]$frame[/classfnc](). + !fn: $cursorPosition() + Returns current cursor position in the editor.[br] + See also [classfnc]$setCursorPosition[/classfnc](). + !fn: $setCursorPosition() + Moves the cursor to place pointed by .[br] + See also [classfnc]$cursorPosition[/classfnc](). + !fn: $selectAll() + Selects whole text inside the editor.[br] + See also [classfnc]$setSelection[/classfnc](), + [classfnc]$cut[/classfnc](), [classfnc]$copy[/classfnc](), + [classfnc]$paste[/classfnc](). + !fn: $setSelection(, ) + Selects characters in the editor starting at position + .[br] + See also [classfnc]$selectAll[/classfnc](), + [classfnc]$cut[/classfnc](), [classfnc]$copy[/classfnc](), + [classfnc]$paste[/classfnc](). + !fn: $copy() + Copies selected text in the editor to the clipboard.[br] + See also [classfnc]$setSelection[/classfnc](), + [classfnc]$cut[/classfnc](), [classfnc]$paste[/classfnc](). + !fn: $cut() + Cuts selected text from the editor to the clipboard.[br] + See also [classfnc]$setSelection[/classfnc](), + [classfnc]$copy[/classfnc](), [classfnc]$paste[/classfnc](). + !fn: $paste() + Pastes text from the clipboard into the editor. The pasted text + will start at cursor position.[br] + See also [classfnc]$setSelection[/classfnc](), + [classfnc]$copy[/classfnc](), [classfnc]$cut[/classfnc](). + !fn: $clear() + Deletes all text from the editor. Equal to calling [classfnc]$setText[/classfnc](""). + !fn: $setDragEnabled() + With this property user can drag text in the lineedit. + !fn: $setReadOnly() + Sets the lineedit to read only mode. + !fn: $setInputMask() + Sets the validation input mask to inputMask.[br] + Example:[br] + [br] + %ledit_example->$setInputMask( "+99 99 99 99 99;_" );[br] + %ledit_example->$setInputMask( "000.000.000.000;_" );[br] + %ledit_example->Ip Number Mask.[br] + %ledit_example->setInputMask( ">AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;#" );[br] + [br] + The mask format understands these mask characters:[br] + Character Meaning[br] + A ASCII alphabetic character required. A-Z, a-z.[br] + a ASCII alphabetic character permitted but not required.[br] + N ASCII alphanumeric character required. A-Z, a-z, 0-9.[br] + n ASCII alphanumeric character permitted but not required.[br] + X Any character required.[br] + x Any character permitted but not required.[br] + 9 ASCII digit required. 0-9.[br] + 0 ASCII digit permitted but not required.[br] + D ASCII digit required. 1-9.[br] + d ASCII digit permitted but not required.[br] + # ASCII digit or plus/minus sign permitted but not required.[br] + > All following alphabetic characters are uppercased.[br] + < All following alphabetic characters are lowercased.[br] + ! Switch off case conversion.[br] + \ Use \ to escape the special characters listed above to use them as separators.[br] + [br] + The mask consists of a string of mask characters and separators, optionally[br] + followed by a semi-colon and the character used for blanks: the blank characters [br] + are always removed from the text after editing. The default blank character is space. [br] + !fn: $returnPressedEvent() + This function is called by the framework when the enter key is pressed. + !fn: $lostFocusEvent() + Called when the lineedit lost focus. + !fn: $textChangedEvent() + This event is called when the text changed, In $0 there is the new text. + !fn: $setCompleter(,) + Provides completions based on an stringlist. + Valid completion_mode are: + PopupCompletion: Current completions are displayed in a popup below the lineedit. + UnfilteredPopupCompletion: All possible completions are displayed in a popup window with the most likely suggestion selected. + InlineCompletion: Completions appear as selected text. + !fn: $disableCompleter() + Disable temporally the completer. + !fn: $enableCompleter() + Enable the completer. + !fn: $removeCompleter() + Remove the completer. + @signals: + !sg: $returnPressed() + This signal is emitted by the default implementation of [classfnc]$returnPressedEvent[/classfnc](). + !sg: $lostFocus() + This signal is emitted by the default implementation of [classfnc]$lostFocusEvent[/classfnc](). + !sg: $textChanged() + This signal is emitted by the default implementation of [classfnc]$textChangedEvent[/classfnc](). + +*/ + + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_lineEdit,"lineedit","widget") + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,text) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,setText) + + // completer + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,setCompleter) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,enableCompleter) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,disableCompleter) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,unsetCompleter) + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,maxLength) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,setMaxLength) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,frame) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,setCursorPosition) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,cursorPosition) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,setFrame) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,selectAll) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,setSelection) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,copy) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,cut) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,paste) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,echoMode) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,setEchoMode) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,clear) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,dragAndDrop) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,setInputMask) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,setReadOnly) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,returnPressedEvent) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,lostFocusEvent) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,textChangedEvent) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_lineEdit,setInputValidator) + + +KVSO_END_REGISTERCLASS(KvsObject_lineEdit) + + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_lineEdit,KvsObject_widget) +m_pCompleter=0; +KVSO_END_CONSTRUCTOR(KvsObject_lineEdit) + +KVSO_BEGIN_DESTRUCTOR(KvsObject_lineEdit) +if (m_pCompleter) +{ + delete m_pCompleter; + m_pCompleter=0; +} +KVSO_END_CONSTRUCTOR(KvsObject_lineEdit) + + +bool KvsObject_lineEdit::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + SET_OBJECT(QLineEdit) + + connect(widget(),SIGNAL(returnPressed()),this,SLOT(slotreturnPressed())); + connect(widget(),SIGNAL(editingFinished()),this,SLOT(slotlostFocus())); + connect(widget(),SIGNAL(textChanged(const QString & )),this,SLOT(slottextChanged(const QString & ))); + return true; +} + +KVSO_CLASS_FUNCTION(lineEdit,text) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setString(((QLineEdit *)widget())->text()); + return true; +} + +KVSO_CLASS_FUNCTION(lineEdit,setText) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETERS_END(c) + ((QLineEdit *)widget())->setText(szText); + return true; +} +KVSO_CLASS_FUNCTION(lineEdit,setInputValidator) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szReg; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("reg_expression",KVS_PT_STRING,0,szReg) + KVSO_PARAMETERS_END(c) + ((QLineEdit *)widget())->setValidator(new QRegExpValidator(QRegExp(szReg),((QLineEdit *)widget()))); + return true; +} +KVSO_CLASS_FUNCTION(lineEdit,maxLength) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QLineEdit *)widget())->maxLength()); + return true; +} + +KVSO_CLASS_FUNCTION(lineEdit,setMaxLength) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t iMaxlen; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("maxlen",KVS_PT_UNSIGNEDINTEGER,0,iMaxlen) + KVSO_PARAMETERS_END(c) + ((QLineEdit *)widget())->setMaxLength(iMaxlen); + return true; +} + +KVSO_CLASS_FUNCTION(lineEdit,frame) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setBoolean(((QLineEdit *)widget())->hasFrame()); + return true; +} + +KVSO_CLASS_FUNCTION(lineEdit,setFrame) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bFrame; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bframe",KVS_PT_BOOL,0,bFrame) + KVSO_PARAMETERS_END(c) + ((QLineEdit *)widget())->setFrame(bFrame); + return true; +} + +KVSO_CLASS_FUNCTION(lineEdit,cursorPosition) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QLineEdit *)widget())->cursorPosition()); + return true; +} + +KVSO_CLASS_FUNCTION(lineEdit,setCursorPosition) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t iPos; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("position",KVS_PT_UNSIGNEDINTEGER,0,iPos) + KVSO_PARAMETERS_END(c) + ((QLineEdit *)widget())->setCursorPosition(iPos); + return true; +} + +KVSO_CLASS_FUNCTION(lineEdit,selectAll) +{ + CHECK_INTERNAL_POINTER(widget()) + ((QLineEdit *)widget())->selectAll(); + return true; +} + +KVSO_CLASS_FUNCTION(lineEdit,setSelection) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uStart,uLen; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("start",KVS_PT_UNSIGNEDINTEGER,0,uStart) + KVSO_PARAMETER("len",KVS_PT_UNSIGNEDINTEGER,0,uLen) + KVSO_PARAMETERS_END(c) + ((QLineEdit *)widget())->setSelection(uStart, uLen); + return true; +} + +KVSO_CLASS_FUNCTION(lineEdit,copy) +{ + CHECK_INTERNAL_POINTER(widget()) + ((QLineEdit *)widget())->copy(); + return true; +} + +KVSO_CLASS_FUNCTION(lineEdit,cut) +{ + CHECK_INTERNAL_POINTER(widget()) + ((QLineEdit *)widget())->cut(); + return true; +} + +KVSO_CLASS_FUNCTION(lineEdit,paste) +{ + CHECK_INTERNAL_POINTER(widget()) + ((QLineEdit *)widget())->paste(); + return true; +} + +KVSO_CLASS_FUNCTION(lineEdit,echoMode) +{ + CHECK_INTERNAL_POINTER(widget()) + int mode = ((QLineEdit *)widget())->echoMode(); + QString szEchomode=""; + for(unsigned int i = 0; i < mode_num; i++) + { + if(mode == mode_cod[i]) + { + szEchomode=mode_tbl[i]; + break; + } + } + c->returnValue()->setString(szEchomode); + return true; +} + +KVSO_CLASS_FUNCTION(lineEdit,setEchoMode) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szMode; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("mode",KVS_PT_STRING,0,szMode) + KVSO_PARAMETERS_END(c) + for(unsigned int i = 0; i < mode_num; i++) + { + if(KviQString::equalCI(szMode, mode_tbl[i])) + { + ((QLineEdit *)widget())->setEchoMode( \ + ((QLineEdit::EchoMode)mode_cod[i])); + return true; + } + } + c->warning(__tr2qs_ctx("Unknown echo mode '%Q'","objects"),&szMode); + return true; +} + +KVSO_CLASS_FUNCTION(lineEdit,clear) +{ + CHECK_INTERNAL_POINTER(widget()) + ((QLineEdit *)widget())->clear(); + return true; +} + +//-| Grifisx & Noldor |-Start: +KVSO_CLASS_FUNCTION(lineEdit,dragAndDrop) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + ((QLineEdit *)widget())->setDragEnabled(bEnabled); + return true; +} + +KVSO_CLASS_FUNCTION(lineEdit,setReadOnly) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bReadonly",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + ((QLineEdit *)widget())->setReadOnly(bEnabled); + return true; +} + +KVSO_CLASS_FUNCTION(lineEdit,setInputMask) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szMask; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("mask",KVS_PT_STRING,0,szMask) + KVSO_PARAMETERS_END(c) + ((QLineEdit *)widget())->setInputMask(szMask); + return true; +} + +KVSO_CLASS_FUNCTION(lineEdit,setCompleter) +{ + CHECK_INTERNAL_POINTER(widget()) + QStringList szCompletionList; + QString szMode; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("mode",KVS_PT_STRING,KVS_PF_OPTIONAL,szMode) + KVSO_PARAMETER("completion_list",KVS_PT_STRINGLIST,0,szCompletionList) + KVSO_PARAMETERS_END(c) + if(m_pCompleter) + { + delete m_pCompleter; + + } + m_pCompleter=new QCompleter(szCompletionList); + QCompleter::CompletionMode mode=QCompleter::PopupCompletion; + if(KviQString::equalCI(szMode,"InlineCompletion")) mode=QCompleter::InlineCompletion; + else if(KviQString::equalCI(szMode,"UnfilteredPopupCompletion")) mode=QCompleter::UnfilteredPopupCompletion; + else if(!KviQString::equalCI(szMode,"PopupCompletion")) + c->warning(__tr2qs_ctx("Unkonwn '%Q' completition mode, switching to default popupCompletition","objects"),&szMode); + m_pCompleter->setCompletionMode(mode); + ((QLineEdit *)widget())->setCompleter(m_pCompleter); + return true; +} +KVSO_CLASS_FUNCTION(lineEdit,enableCompleter) +{ + CHECK_INTERNAL_POINTER(widget()) + if (m_pCompleter) ((QLineEdit *)widget())->setCompleter(m_pCompleter); + return true; +} +KVSO_CLASS_FUNCTION(lineEdit,disableCompleter) +{ + CHECK_INTERNAL_POINTER(widget()) + ((QLineEdit *)widget())->setCompleter(0); + return true; +} +KVSO_CLASS_FUNCTION(lineEdit,unsetCompleter) +{ + CHECK_INTERNAL_POINTER(widget()) + if (m_pCompleter){ + ((QLineEdit *)widget())->setCompleter(0); + delete m_pCompleter; + m_pCompleter=0; + } + return true; +} + + +KVSO_CLASS_FUNCTION(lineEdit,returnPressedEvent) +{ + emitSignal("returnPressed",c); + return true; +} + +void KvsObject_lineEdit::slotreturnPressed() +{ + KviKvsVariantList * params = 0; + callFunction(this,"returnPressedEvent",params); + +} + +KVSO_CLASS_FUNCTION(lineEdit,lostFocusEvent) +{ + emitSignal("lostFocus",c); + return true; +} + +void KvsObject_lineEdit::slotlostFocus() +{ + KviKvsVariantList * params = 0; + callFunction(this,"lostFocusEvent",params); +} + +KVSO_CLASS_FUNCTION(lineEdit,textChangedEvent) +{ + emitSignal("textChanged",c,c->params()); + return true; + +} + +void KvsObject_lineEdit::slottextChanged(const QString &text) +{ + KviKvsVariantList params(new KviKvsVariant(text)); + callFunction(this,"textChangedEvent",¶ms); +} + + + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_lineEdit.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES + diff --git a/src/modules/objects/KvsObject_lineEdit.h b/src/modules/objects/KvsObject_lineEdit.h new file mode 100644 index 000000000..f561bf682 --- /dev/null +++ b/src/modules/objects/KvsObject_lineEdit.h @@ -0,0 +1,90 @@ +#ifndef _CLASS_LINEEDIT_H_ +#define _CLASS_LINEEDIT_H_ +//============================================================================= +// +// File : KvsObject_lineEdit.h +// Creation date : Wed 20 Sep 2000 04:34:40 CEST by Krzysztof Godlewski +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000 Krzysztof Godlewski +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + + +#include "KvsObject_widget.h" + +//#warning "Signals !" +#include +#include "object_macros.h" + +class KvsObject_lineEdit : public KvsObject_widget +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_lineEdit) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + QCompleter * m_pCompleter; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool setCompleter(KviKvsObjectFunctionCall *c); + bool enableCompleter(KviKvsObjectFunctionCall *c); + bool disableCompleter(KviKvsObjectFunctionCall *c); + bool unsetCompleter(KviKvsObjectFunctionCall *c); + + bool text(KviKvsObjectFunctionCall *c); + bool setText(KviKvsObjectFunctionCall *c); + bool maxLength(KviKvsObjectFunctionCall *c); + bool setMaxLength(KviKvsObjectFunctionCall *c); + bool frame(KviKvsObjectFunctionCall *c); + bool setCursorPosition(KviKvsObjectFunctionCall *c); + bool cursorPosition(KviKvsObjectFunctionCall *c); + bool setFrame(KviKvsObjectFunctionCall *c); + bool selectAll(KviKvsObjectFunctionCall *c); + bool setSelection(KviKvsObjectFunctionCall *c); + bool copy(KviKvsObjectFunctionCall *c); + bool cut(KviKvsObjectFunctionCall *c); + + bool paste(KviKvsObjectFunctionCall *c); + bool echoMode(KviKvsObjectFunctionCall *c); + bool setEchoMode(KviKvsObjectFunctionCall *c); + bool clear(KviKvsObjectFunctionCall *c); + bool dragAndDrop(KviKvsObjectFunctionCall *c); + bool setInputMask(KviKvsObjectFunctionCall *c); + bool setReadOnly(KviKvsObjectFunctionCall *c); + + bool returnPressedEvent(KviKvsObjectFunctionCall *c); + + bool lostFocusEvent(KviKvsObjectFunctionCall *c); + + bool textChangedEvent(KviKvsObjectFunctionCall *c); + + + bool setInputValidator(KviKvsObjectFunctionCall *c); +protected slots: + void slotreturnPressed(); + void slotlostFocus(); + void slottextChanged(const QString &); + +}; + + +#endif // ! _CLASS_LINEEDIT_H_ diff --git a/src/modules/objects/KvsObject_list.cpp b/src/modules/objects/KvsObject_list.cpp new file mode 100644 index 000000000..a07b3a3e2 --- /dev/null +++ b/src/modules/objects/KvsObject_list.cpp @@ -0,0 +1,342 @@ +//============================================================================= +// +// File : KvsObject_list.cpp +// Creation date : Wed Sep 09 2000 21:07:55 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================ + +#include "kvi_debug.h" +#include "KviMemory.h" +#include "KviLocale.h" +#include "KvsObject_list.h" +#include + + +/* + @doc: list + @keyterms: + list object class, sorted list + @title: + list class + @type: + class + @short: + Abstracts a double linked list of strings + @inherits: + [class]object[/class] + @description: + This object class abstracts a double linked list of strings. + You can insert/remove items by zero based position, at the end (tail) or at the + beginning (head). The list incorporates an efficient iteration + method by using the [classfnc:list]$moveFirst[/classfnc](),[classfnc:list]$moveLast[/classfnc](), + [classfnc:list]$moveNext[/classfnc](),[classfnc:list]$movePrev[/classfnc](), + [classfnc:list]$current[/classfnc]() and [classfnc:list]$eof[/classfnc]() functions. + @functions: + !fn: $count() + Returns the number of items in the list + + !fn: $isEmpty() + Returns $true if the list is empty, $false otherwise. + + !fn: $clear() + Removes all the items from the list.This is the same as + [classfnc:list]$removeAll[/classfnc](). + + !fn: $removeAll() + Removes all the items from the list. This is the same as + [classfnc:list]$clear[/classfnc](). + + !fn: $append() + Inserts the at the end (tail) of the list. + + !fn: $prepend() + Inserts the at the beginning (head) of the list. + + !fn: $insert(,) + Inserts the at zero-based position in the list. + If is greater or equal to [classfnc:list]$count[/classfnc]() + then the item is simply appended to the end of the list. + + !fn: $add(,) + This is exactly the same as [classfnc:list]$insert[/classfnc](). + + !fn: $item() + Returns the item at zero-based . If is greater + or equal to [classfnc:list]$count[/classfnc]() (beyond the end of the list) + then [fnc]$nothing[/fnc] is returned. + + !fn: $remove() + Removes the item at zero-based . Returns $true + if the item was successfully removed and $false otherwise (i.e. + pointed beyond the end of the list). + + !fn: $removeFirst() + Removes the first item from the list. Returns $true + if the item was successfully removed (the list was not empty) + and $false otherwise. + + !fn: $removeLast() + Removes the last item from the list. Returns $true + if the item was successfully removed (the list was not empty) + and $false otherwise. + + !fn: $removeCurrent() + Removes the current item from the list. Returns $true + if the item was successfully removed or $false otherwise. + Invalidates any iteration operation. + + !fn: $moveFirst() + Moves the iterator to the first item in the list and returns + $true if the move was succesfull (i.e., the list is not empty) + and $false otherwise. + + !fn: $moveLast() + Moves the iterator to the last item in the list and returns + $true if the move was succesfull (i.e., the list is not empty) + and $false otherwise. + + !fn: $movePrev() + Moves the iterator to the previous item and returns $true + if the move was succesfull (i.e., there IS a previous item) + and $false otherwise. + + !fn: $moveNext() + Moves the iterator to the next item and returns $true + if the move was succesfull (i.e., there IS a next item) + and $false otherwise. + + !fn: $eof() + Returns $true if the iterator points to a valid + item in the list (and thus [classfnc:list]$current[/classfnc]() + would return a valid value) and $false otherwise. + + !fn: $current() + Returns the item pointed by the current iterator + or [fnc]$nothing[/fnc] is the iterator is not valid (points + beyond the end of the list). +*/ + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_list,"list","object") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,count) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,isEmpty) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,clear) + KVSO_REGISTER_HANDLER(KvsObject_list,"removeAll",clear) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,append) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,prepend) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,insert) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,insert) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,at) + KVSO_REGISTER_HANDLER(KvsObject_list,"item",at) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,remove) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,removeFirst) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,removeLast) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,removeCurrent) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,moveFirst) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,moveNext) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,movePrev) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,moveLast) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,sort) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,eof) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_list,current) +KVSO_END_REGISTERCLASS(KvsObject_list) + + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_list,KviKvsObject) + m_pDataList = new KviPointerList; + m_pDataList->setAutoDelete(true); + m_pDataList->first(); +KVSO_END_CONSTRUCTOR(KvsObject_list) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_list) +delete m_pDataList; +m_pDataList = 0; +KVSO_END_CONSTRUCTOR(KvsObject_list) + +KVSO_CLASS_FUNCTION(list,current) +{ + CHECK_INTERNAL_POINTER(m_pDataList) + if(!m_pDataList->count()) + { + c->returnValue()->setNothing(); + return true; + } + KviKvsVariant * v = m_pDataList->safeCurrent(); + if(v)c->returnValue()->copyFrom(*v); + else c->returnValue()->setNothing(); + return true; +} + +KVSO_CLASS_FUNCTION(list,eof) +{ + CHECK_INTERNAL_POINTER(m_pDataList) + c->returnValue()->setBoolean(m_pDataList->current() != 0); + return true; +} + +KVSO_CLASS_FUNCTION(list,moveLast) +{ + CHECK_INTERNAL_POINTER(m_pDataList) + c->returnValue()->setBoolean(m_pDataList->last() != 0); + return true; +} + +KVSO_CLASS_FUNCTION(list,movePrev) +{ + CHECK_INTERNAL_POINTER(m_pDataList) + c->returnValue()->setBoolean(m_pDataList->prev() != 0); + return true; +} + +KVSO_CLASS_FUNCTION(list,moveNext) +{ + CHECK_INTERNAL_POINTER(m_pDataList) + c->returnValue()->setBoolean(m_pDataList->next() != 0); + return true; +} + +KVSO_CLASS_FUNCTION(list,moveFirst) +{ + CHECK_INTERNAL_POINTER(m_pDataList) + c->returnValue()->setBoolean(m_pDataList->first() != 0); + return true; +} + +KVSO_CLASS_FUNCTION(list,removeLast) +{ + CHECK_INTERNAL_POINTER(m_pDataList) + c->returnValue()->setBoolean(m_pDataList->removeLast()); + return true; +} + +KVSO_CLASS_FUNCTION(list,removeCurrent) +{ + CHECK_INTERNAL_POINTER(m_pDataList) + if(m_pDataList->count()) + { + m_pDataList->removeCurrent(); + c->returnValue()->setBoolean(true); + } else { + c->returnValue()->setBoolean(false); + } + return true; +} + +KVSO_CLASS_FUNCTION(list,removeFirst) +{ + CHECK_INTERNAL_POINTER(m_pDataList) + c->returnValue()->setBoolean(m_pDataList->removeFirst()); + return true; +} + +KVSO_CLASS_FUNCTION(list,remove) +{ + CHECK_INTERNAL_POINTER(m_pDataList) + kvs_uint_t uIndex; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_UINT,0,uIndex) + KVSO_PARAMETERS_END(c) + c->returnValue()->setBoolean(m_pDataList->remove(uIndex)); + return true; +} + +KVSO_CLASS_FUNCTION(list,at) +{ + CHECK_INTERNAL_POINTER(m_pDataList) + kvs_uint_t uIndex; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_UINT,0,uIndex) + KVSO_PARAMETERS_END(c) + KviKvsVariant * v = m_pDataList->at(uIndex); + if(v)c->returnValue()->copyFrom(*v); + else c->returnValue()->setNothing(); + return true; +} + +KVSO_CLASS_FUNCTION(list,insert) +{ + CHECK_INTERNAL_POINTER(m_pDataList) + kvs_uint_t uIndex; + KviKvsVariant * pVar; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_UINT,0,uIndex) + KVSO_PARAMETER("item",KVS_PT_VARIANT,0,pVar) + KVSO_PARAMETERS_END(c) + m_pDataList->insert(uIndex,new KviKvsVariant(*pVar)); + return true; +} + +KVSO_CLASS_FUNCTION(list,prepend) +{ + CHECK_INTERNAL_POINTER(m_pDataList) + KviKvsVariant * pVar; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("item",KVS_PT_VARIANT,0,pVar) + KVSO_PARAMETERS_END(c) + m_pDataList->prepend(new KviKvsVariant(*pVar)); + return true; +} + +KVSO_CLASS_FUNCTION(list,append) +{ + CHECK_INTERNAL_POINTER(m_pDataList) + KviKvsVariant * pVar; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("item",KVS_PT_VARIANT,0,pVar) + KVSO_PARAMETERS_END(c) + m_pDataList->append(new KviKvsVariant(*pVar)); + if (m_pDataList->count()==1) m_pDataList->first(); + return true; +} + +KVSO_CLASS_FUNCTION(list,clear) +{ + CHECK_INTERNAL_POINTER(m_pDataList) + m_pDataList->clear(); + return true; +} + +inline int kvi_compare(const KviKvsVariant * p1,const KviKvsVariant * p2) +{ + return p1->compare(p2); +} + +KVSO_CLASS_FUNCTION(list,sort) +{ + CHECK_INTERNAL_POINTER(m_pDataList) + m_pDataList->sort(); + return true; +} + +KVSO_CLASS_FUNCTION(list,isEmpty) +{ + CHECK_INTERNAL_POINTER(m_pDataList) + c->returnValue()->setBoolean(m_pDataList->isEmpty()); + return true; +} + +KVSO_CLASS_FUNCTION(list,count) +{ + CHECK_INTERNAL_POINTER(m_pDataList) + c->returnValue()->setInteger(m_pDataList->count()); + return true; +} + diff --git a/src/modules/objects/KvsObject_list.h b/src/modules/objects/KvsObject_list.h new file mode 100644 index 000000000..46a4c0c4b --- /dev/null +++ b/src/modules/objects/KvsObject_list.h @@ -0,0 +1,64 @@ +#ifndef _CLASS_LIST_H_ +#define _CLASS_LIST_H_ +//============================================================================= +// +// File : KvsObject_list.h +// Creation date : Wed Sep 09 2000 21:07:01 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" +#include "KviCString.h" +#include "KviPointerList.h" +#include "KviKvsVariant.h" +#include "object_macros.h" + + +class KvsObject_list : public KviKvsObject +{ +public: + KVSO_DECLARE_OBJECT(KvsObject_list) +protected: + KviPointerList * m_pDataList; +protected: + KviPointerList * dataList() const { return m_pDataList; }; +public: + bool count(KviKvsObjectFunctionCall *c); + bool isEmpty(KviKvsObjectFunctionCall *c); + bool clear(KviKvsObjectFunctionCall *c); + bool append(KviKvsObjectFunctionCall *c); + bool prepend(KviKvsObjectFunctionCall *c); + bool insert(KviKvsObjectFunctionCall *c); + bool at(KviKvsObjectFunctionCall *c); + bool remove(KviKvsObjectFunctionCall *c); + bool removeFirst(KviKvsObjectFunctionCall *c); + bool removeLast(KviKvsObjectFunctionCall *c); + bool removeCurrent(KviKvsObjectFunctionCall *c); + bool moveFirst(KviKvsObjectFunctionCall *c); + bool moveNext(KviKvsObjectFunctionCall *c); + bool movePrev(KviKvsObjectFunctionCall *c); + bool moveLast(KviKvsObjectFunctionCall *c); + bool eof(KviKvsObjectFunctionCall *c); + bool current(KviKvsObjectFunctionCall *c); + bool sort(KviKvsObjectFunctionCall *c); +}; + + +#endif //_CLASS_LIST_H_ diff --git a/src/modules/objects/KvsObject_listWidget.cpp b/src/modules/objects/KvsObject_listWidget.cpp new file mode 100644 index 000000000..773cfe0b4 --- /dev/null +++ b/src/modules/objects/KvsObject_listWidget.cpp @@ -0,0 +1,680 @@ +//============================================================================= +// +// File : KvsObject_listWidget.cpp +// Creation date : Sat Oct 2 03:40:28 CET 2004 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2004-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviError.h" +#include "KviLocale.h" +#include "kvi_debug.h" +#include "KvsObject_list.h" +#include "KvsObject_listWidget.h" +#include "KvsObject_pixmap.h" +#include "KviIconManager.h" +#include + +const int item_flags[] = { + Qt::NoItemFlags, + Qt::ItemIsSelectable, + Qt::ItemIsEditable, + Qt::ItemIsDragEnabled, + Qt::ItemIsDropEnabled, + Qt::ItemIsUserCheckable, + Qt::ItemIsEnabled, + Qt::ItemIsTristate +}; + +const char * const itemflags_tbl[] = { + "noitemflag", + "selectable", + "editable", + "dragEnabled", + "dropEnabled", + "userCheckable", + "enabled", + "tristate" +}; + +#define itemflags_num (sizeof(itemflags_tbl) / sizeof(itemflags_tbl[0])) + +/* + @doc:listbox + @title: + listbox class + @type: + class + @short: + A widget displaying a list of items. + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + The listbox class is a widget displaying a list of string items.[br] + The listbox can operate in four selection modes: single, multi, extended + and none. In the "single" mode only one item can be selected at a time + and that item is also the current one. In the "multi" mode multiple + items can be selected and unselected and the current item may or may not + be one of the selected items. In the "extended" mode multiple items + can be selected but they must be selected in a single mouse action + or by keeping the shift button pressed while clicking on the item. + In this mode the current item is always one of the selected items.[br] + In the "none" mode no items can be selected and the current item + may be any item in the list.[br] + In most situations you will operate the listwidget in "single" mode + (and this is the default mode set at widget creation). + @functions: + !fn: $setSelectionMode() + Sets the current selection mode specified by the parameter + that can be one of the following string:[br] + "single" : only one item can be selected at a time[br] + "multi" : multiple items can be selected at a time[br] + "extended" : multiple items can be selected but only in a single mouse interaction[br] + "none" : no items can be selected[br] + The default mode is "single" + !fn: $setFlag(,, , ...) + Sets the flags for the item at index idz to the given flags. These determine whether the item can be selected or modified. This is often used to disable an item. + Supported flags are: + - noitemflag : no flag sets; + - selectable : item is selecatble; + - editable : item is editable; + - dragEnabled : item can dragged; + - dropEnabled : item can used as drop target; + - userCheckable : item is checkable; + - enabled :item is enabled; + - tristate : item is checkable with three separate states. + !fn: $setChecked() + Sets the eventual item check box 'checked state' to . + !fn: $isChecked() + Returns '1' if the eventual item check box is checked, '0' otherwise.[br] + !fn: $selectionMode() + Returns the current selection mode + !fn: $insertItem(, ) + Inserts a text item at position . If index is negative or + not specified the item is appended. + !fn: $changeItem(, ) + Changes text of item at to . + !fn: $removeItem() + Removes item at given index. + !fn: $count() + Returns number of items in the widget. + !fn: $currentText() + Returns the text of the currently selected item. + !fn: $currentItem() + Returns index of current item or -1 if no item is current. + !fn: $textAt() + Returns item at given index. + !fn: $setCurrentItem() + Sets the current listbox item. + !fn: $clear() + Removes all the items + !fn: $setFont(,,[,, , ...]) + Set the font's family, size and style, at index ; valid flag for style are:[br] + italic, bold, underline, overline, strikeout, fixedpitch [br] + If you just want to set a style without altering the preset font size and family, you can use $setFont() like this:[br] + %widget->$setFont(0,0,"bold") + !fn: $onItemEvent() + This function is called by KVIrc when the current item pointed by the mouse changes and gives in $0 the item index. + !fn: $itemRect() + Returns the rectangle on the screen that item occupies, or an invalid rectangle if item is 0 or is not currently visible. + !fn: $itemEnteredEvent() + This function is called by KVIrc when the mouse cursor enters an item. + !fn: $selectionChangedEvent() + This function is called by KVIrc when the selection in the listbox changes. + !fn: $currentItemChangedEvent() + This function is called by KVIrc when the current item changes. + !fn: $itemChangedEvent() + This function is called by KVIrc when the current data item changes (i.e. the user check a ckeckable item) . + + @signals: + !sg: $currentItemChanged() + This signal is emitted by the default implementation of [classfnc]$currentItemChangedEvent[/classfnc]().[br] + !sg: $itemChanged() + This signal is emitted by the default implementation of [classfnc]$itemChangedEvent[/classfnc]().[br] + !sg: $itemEntered() + This signal is emitted by the default implementation of [classfnc]$itemEnteredEvent[/classfnc]().[br] + !sg: $selectionChanged() + This signal is emitted by the default implementation of [classfnc]$selectionChangedEvent[/classfnc]().[br] + */ + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_listWidget,"listbox","widget") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,insertItem) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,insertWidgetItem) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,changeItem) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,removeItem) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,clear) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,count) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,currentText) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,currentItem) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,textAt); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,itemAt); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,itemRect); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,setCurrentItem); + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,selectedItems); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,setSelected); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,isSelected); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,setFont); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,setIcon); + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,setFlags) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,setChecked); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,isChecked); + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,setSelectionMode); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,selectionMode); + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,setForeground); + + // events + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,currentItemChangedEvent); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,itemChangedEvent); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_listWidget,itemEnteredEvent); + KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KvsObject_listWidget,"selectionChangedEvent") + + +KVSO_END_REGISTERCLASS(KvsObject_listWidget) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_listWidget,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_listWidget) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_listWidget) + +KVSO_END_CONSTRUCTOR(KvsObject_listWidget) + +bool KvsObject_listWidget::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + SET_OBJECT(QListWidget) + obj->setSelectionMode(QAbstractItemView::SingleSelection); + connect(obj,SIGNAL(itemSelectionChanged()),this,SLOT(selectionChanged())); + connect(obj,SIGNAL(currentItemChanged(QListWidgetItem *,QListWidgetItem *)),this,SLOT(currentItemChanged(QListWidgetItem *,QListWidgetItem *))); + connect(obj,SIGNAL(itemEntered(QListWidgetItem *)),this,SLOT(slotItemEntered(QListWidgetItem *))); + connect(obj,SIGNAL(itemChanged(QListWidgetItem *)),this,SLOT(slotItemChanged(QListWidgetItem *))); + + return true; +} + +KVSO_CLASS_FUNCTION(listWidget,insertItem) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iRow; + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETER("index",KVS_PT_INT,KVS_PF_OPTIONAL,iRow) + KVSO_PARAMETERS_END(c) + if (c->parameterCount()==2) ((QListWidget *)widget())->insertItem(iRow, szText); + else ((QListWidget *)widget())->addItem(szText); + return true; +} + +KVSO_CLASS_FUNCTION(listWidget,setFlags) +{ + CHECK_INTERNAL_POINTER(widget()) + QStringList itemflags; + kvs_uint_t iIdx; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,iIdx) + KVSO_PARAMETER("flags",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,itemflags) + KVSO_PARAMETERS_END(c) + int flag,sum=0; + QListWidgetItem *pItem=((QListWidget *)widget())->item(iIdx); + if(!pItem) return true; + for ( int i=0;isetCheckState(Qt::Unchecked); + sum = sum | flag; + } + else + c->warning(__tr2qs_ctx("Unknown item flag '%Q'","objects"),&itemflags.at(i)); + } + pItem->setFlags((Qt::ItemFlags)sum); + return true; +} +KVSO_CLASS_FUNCTION(listWidget,setChecked) +{ + bool bChecked; + kvs_uint_t iIdx; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,iIdx) + KVSO_PARAMETER("bChecked",KVS_PT_BOOL,0,bChecked) + KVSO_PARAMETERS_END(c) + QListWidgetItem *pItem=((QListWidget *)widget())->item(iIdx); + if(!pItem) return true; + pItem->setCheckState(bChecked?Qt::Checked:Qt::Unchecked); + return true; +} + +KVSO_CLASS_FUNCTION(listWidget,isChecked) +{ + kvs_uint_t iIdx; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,iIdx) + KVSO_PARAMETERS_END(c) + QListWidgetItem *pItem=((QListWidget *)widget())->item(iIdx); + if(!pItem) return true; + c->returnValue()->setBoolean(pItem->checkState()==Qt::Checked?1:0); + return true; +} + +KVSO_CLASS_FUNCTION(listWidget,setFont) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szFamily; + QStringList szListStyle; + kvs_int_t iSize,iIdx; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_INTEGER,0,iIdx) + KVSO_PARAMETER("size",KVS_PT_INTEGER,0,iSize) + KVSO_PARAMETER("family",KVS_PT_STRING,0,szFamily) + KVSO_PARAMETER("style",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,szListStyle) + KVSO_PARAMETERS_END(c) + QListWidgetItem *pItem=((QListWidget *)widget())->item(iIdx); + if(!pItem) return true; + QFont font=widget()->font(); + if(!szFamily.isEmpty()) font.setFamily(szFamily); + if(iSize) font.setPointSize(iSize); + QString szStyle; + for(int i=0;iwarning(__tr2qs_ctx("Unknown style '%Q'","objects"),&szStyle); + } + pItem->setFont(font); + return true; +} +KVSO_CLASS_FUNCTION(listWidget,setIcon) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uIdx; + KviKvsObject *obPixmap; + kvs_hobject_t obHpixmap; + KviKvsVariant * vPixmap; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uIdx) + KVSO_PARAMETER("pixmap",KVS_PT_VARIANT,0,vPixmap) + KVSO_PARAMETERS_END(c) + QListWidgetItem *pItem=((QListWidget *)widget())->item(uIdx); + if(!pItem) return true; + + QPixmap *pix = 0; + if (vPixmap->isEmpty()) {pItem->setIcon(QIcon());return true;} + if(vPixmap->isHObject()) + { + vPixmap->asHObject(obHpixmap); + obPixmap=KviKvsKernel::instance()->objectController()->lookupObject(obHpixmap); + if (!obPixmap->inheritsClass("pixmap")) + { + c->warning(__tr2qs_ctx("Pixmap object or image Id required","objects")); + return true; + } + pix=((KvsObject_pixmap *)obPixmap)->getPixmap(); + } else { + QString szPix; + vPixmap->asString(szPix); + pix=g_pIconManager->getImage(szPix); + if(!pix) + { + c->warning(__tr2qs_ctx("Error occured: the suitable file '%Q' is not of the correct format or it is not a valid icon number.","objects"),&szPix); + return true; + } + } + if(pix){ + pItem->setIcon(*pix); + } + else{ + pItem->setIcon(QIcon()); + } + return true; +} +KVSO_CLASS_FUNCTION(listWidget,setForeground) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iCol1,iCol2,iCol3,iOpacity,iIdx; + QString szColorMode,szColor; + KviKvsVariant *var1,*var2,*var3; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_INTEGER,0,iIdx) + KVSO_PARAMETER("Color_1_Or_Colorname",KVS_PT_VARIANT,0,var1) + KVSO_PARAMETER("Color_2",KVS_PT_VARIANT,KVS_PF_OPTIONAL,var2) + KVSO_PARAMETER("Colo3_3",KVS_PT_VARIANT,KVS_PF_OPTIONAL,var3) + KVSO_PARAMETER("color_mode",KVS_PT_STRING,KVS_PF_OPTIONAL,szColorMode) + KVSO_PARAMETER("opacity",KVS_PT_INT,KVS_PF_OPTIONAL,iOpacity) + KVSO_PARAMETERS_END(c) + QListWidgetItem *pItem=((QListWidget *)widget())->item(iIdx); + if(!pItem) return true; + QColor col; + if (!var1->asInteger(iCol1)) + { + var1->asString(szColor); + if (c->paramCount()<3) iOpacity=255; + else + { + if (!var2->asInteger(iOpacity)) + { + c->warning(__tr2qs_ctx("The opacity parameter didn't evaluate to integer","objects")); + return true; + } + } + col.setNamedColor(szColor); + col.setAlpha(iOpacity); + } + else + { + if(c->paramCount()<4) + { + c->error(__tr2qs_ctx("Color name or triplette rgb/hsv value required","objects")); + return true; + } + if (!var2->asInteger(iCol2)||!var3->asInteger(iCol3)) + { + c->error(__tr2qs_ctx("One of the triplette parameters didn't evaluate to an integer","objects"));\ + return true; + } + if (c->paramCount()<5) iOpacity=255; + if(KviQString::equalCI(szColorMode, "HSV")) + col.setHsv(iCol1,iCol2,iCol3,iOpacity); + else + col.setRgb(iCol1,iCol2,iCol3,iOpacity); + } + QBrush brush=pItem->foreground(); + brush.setColor(col); + pItem->setForeground(brush); + return true; +} +KVSO_CLASS_FUNCTION(listWidget,clear) +{ + CHECK_INTERNAL_POINTER(widget()) + ((QListWidget *)widget())->clear(); + return true; +} + +KVSO_CLASS_FUNCTION(listWidget,changeItem) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t iIndex,cnt; + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,iIndex) + KVSO_PARAMETERS_END(c) + if (szText.isEmpty()) c->warning(__tr2qs_ctx("No string parameter given - using empty string","objects")); + if(iIndex >= (cnt = ((QListWidget *)widget())->count())) + { + c->warning(__tr2qs_ctx("Item index [%d] is too big - defaulting to " + "$count() - 1 [%d]","objects"), iIndex, cnt); + iIndex = cnt - 1; + } + ((QListWidget *)widget())->item(iIndex)->setText(szText); + return true; +} + + +KVSO_CLASS_FUNCTION(listWidget,removeItem) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t iIndex,cnt; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,iIndex) + KVSO_PARAMETERS_END(c) + if(iIndex >= (cnt = ((QListWidget *)widget())->count())) + { + c->warning(__tr2qs_ctx("Item index [%d] is too big - defaulting to " \ + "$count() - 1 [%d]","objects"), iIndex, cnt); + iIndex = cnt - 1; + } + delete ((QListWidget *)widget())->takeItem(iIndex); + return true; +} + +KVSO_CLASS_FUNCTION(listWidget,count) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QListWidget *)widget())->count()); + return true; +} +KVSO_CLASS_FUNCTION(listWidget,currentText) +{ + CHECK_INTERNAL_POINTER(widget()) + QString text; + QListWidgetItem *item=((QListWidget *)widget())->currentItem(); + if (item) text=item->text(); + else text=""; + c->returnValue()->setString(text); + return true; +} +KVSO_CLASS_FUNCTION(listWidget,currentItem) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QListWidget *)widget())->currentRow()); + return true; +} + +KVSO_CLASS_FUNCTION(listWidget,textAt) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t iIndex; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,iIndex) + KVSO_PARAMETERS_END(c) + c->returnValue()->setString(((QListWidget *)widget())->item(iIndex)->text()); + return true; +} +KVSO_CLASS_FUNCTION(listWidget,setCurrentItem) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t iIndex; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,iIndex) + KVSO_PARAMETERS_END(c) + ((QListWidget *)widget())->setCurrentRow(iIndex); + return true; +} +KVSO_CLASS_FUNCTION(listWidget,setSelectionMode) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szMode; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("selection_mode",KVS_PT_STRING,0,szMode) + KVSO_PARAMETERS_END(c) + QAbstractItemView::SelectionMode iMode = QAbstractItemView::SingleSelection; + if(KviQString::equalCI(szMode,"single")) iMode = QAbstractItemView::SingleSelection; + else if(KviQString::equalCI(szMode,"multi")) iMode = QAbstractItemView::MultiSelection; + else if(KviQString::equalCI(szMode,"extended")) iMode = QAbstractItemView::ExtendedSelection; + else if(KviQString::equalCI(szMode,"none")) iMode = QAbstractItemView::NoSelection; + else c->warning(__tr2qs_ctx("Invalid selection mode '%Q' assuming single","objects"),&szMode); + ((QListWidget *)widget())->setSelectionMode(iMode); + return true; +} +KVSO_CLASS_FUNCTION(listWidget,selectionMode) +{ + CHECK_INTERNAL_POINTER(widget()) + switch(((QListWidget *)widget())->selectionMode()) + { + case QAbstractItemView::SingleSelection: c->returnValue()->setString("single"); break; + case QAbstractItemView::MultiSelection: c->returnValue()->setString("multi"); break; + case QAbstractItemView::ExtendedSelection: c->returnValue()->setString("extended"); break; + case QAbstractItemView::NoSelection: c->returnValue()->setString("none"); break; + default: c->returnValue()->setString("single"); break; + } + return true; +} + +KVSO_CLASS_FUNCTION(listWidget,insertWidgetItem) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsObject *pObject; + kvs_int_t iIndex; + kvs_hobject_t hWid; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hWid) + KVSO_PARAMETER("index",KVS_PT_INT,0,iIndex) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hWid); + if(pObject==this) + { + c->warning(__tr2qs_ctx("Can't insert the listwidget itself!","objects")); + return true; + } + if(!pObject->object()->isWidgetType()) + { + c->warning(__tr2qs_ctx("Can't insert a non-widget object","objects")); + return true; + } + QWidget *wi=((QWidget *)(pObject->object())); + QListWidgetItem *item=((QListWidget *)widget())->item(iIndex); + ((QListWidget *)widget())->setItemWidget(item,wi); + return true; +} +KVSO_CLASS_FUNCTION(listWidget,selectedItems) +{ + CHECK_INTERNAL_POINTER(widget()) + QList list=((QListWidget *)widget())->selectedItems(); + KviKvsArray * pArray = new KviKvsArray(); + c->returnValue()->setArray(pArray); + for (int i=0;irow(list.at(i)); + pArray->set(i,new KviKvsVariant(index)); + } + return true; +} + +KVSO_CLASS_FUNCTION(listWidget,setSelected) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bSel; + kvs_uint_t uIndex; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex) + KVSO_PARAMETER("benabled",KVS_PT_BOOLEAN,0,bSel) + KVSO_PARAMETERS_END(c) + ((QListWidget *)widget())->item(uIndex)->setSelected(bSel); + return true; +} +KVSO_CLASS_FUNCTION(listWidget,isSelected) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uIndex; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex) + KVSO_PARAMETERS_END(c) + c->returnValue()->setBoolean(((QListWidget *)widget())->item(uIndex)->isSelected()); + return true; +} +KVSO_CLASS_FUNCTION(listWidget,itemAt) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uX,uY; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("uX",KVS_PT_UNSIGNEDINTEGER,0,uX) + KVSO_PARAMETER("uY",KVS_PT_UNSIGNEDINTEGER,0,uY) + KVSO_PARAMETERS_END(c) + c->returnValue()->setInteger(((QListWidget *)widget())->row(((QListWidget *)widget())->itemAt(QPoint(uX,uY)))); + return true; +} +KVSO_CLASS_FUNCTION(listWidget,itemRect) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uIndex; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("iIndex",KVS_PT_UNSIGNEDINTEGER,0,uIndex) + KVSO_PARAMETERS_END(c) + QRect rect=((QListWidget *)widget())->visualItemRect(((QListWidget *)widget())->item(uIndex)); + KviKvsArray * a = new KviKvsArray(); + a->set(0,new KviKvsVariant((kvs_int_t)rect.left())); + a->set(1,new KviKvsVariant((kvs_int_t)rect.top())); + a->set(2,new KviKvsVariant((kvs_int_t)rect.width())); + a->set(3,new KviKvsVariant((kvs_int_t)rect.height())); + c->returnValue()->setArray(a); + return true; +} + +KVSO_CLASS_FUNCTION(listWidget,currentItemChangedEvent) +{ + emitSignal("currentItemChanged",c,c->params()); + return true; +} +KVSO_CLASS_FUNCTION(listWidget,itemChangedEvent) +{ + emitSignal("itemChanged",c,c->params()); + return true; +} + +KVSO_CLASS_FUNCTION(listWidget,itemEnteredEvent) +{ + emitSignal("itemEntered",c,c->params()); + + return true; +} + +//slots +void KvsObject_listWidget::currentItemChanged(QListWidgetItem *currentItem,QListWidgetItem *) +{ + if (!currentItem) callFunction(this,"currentItemChangedEvent",0,0); + else + { + KviKvsVariantList params(new KviKvsVariant(currentItem->text())); + callFunction(this,"currentItemChangedEvent",0,¶ms); + } + +} +void KvsObject_listWidget::selectionChanged() +{ + callFunction(this,"selectionChangedEvent",0,0); +} + + +void KvsObject_listWidget::slotItemEntered(QListWidgetItem *item) +{ + KviKvsVariantList params(new KviKvsVariant((kvs_int_t)((QListWidget *)widget())->row(item))); + callFunction(this,"itemEnteredEvent",0,¶ms); +} + +void KvsObject_listWidget::slotItemChanged(QListWidgetItem *item) +{ + KviKvsVariantList params(new KviKvsVariant((kvs_int_t)((QListWidget *)widget())->row(item))); + callFunction(this,"itemChangedEvent",0,¶ms); +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_listWidget.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES + diff --git a/src/modules/objects/KvsObject_listWidget.h b/src/modules/objects/KvsObject_listWidget.h new file mode 100644 index 000000000..3fb204488 --- /dev/null +++ b/src/modules/objects/KvsObject_listWidget.h @@ -0,0 +1,81 @@ +#ifndef _CLASS_LISTBOX_H_ +#define _CLASS_LISTBOX_H_ +//============================================================================= +// +// File : KvsObject_listWidget.h +// Creation date : Sat Oct 2 03:40:28 CET 2004 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2004-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include "KvsObject_widget.h" +#include +#include "object_macros.h" + +class KvsObject_listWidget: public KvsObject_widget +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_listWidget) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + + bool insertItem(KviKvsObjectFunctionCall *c); + bool changeItem(KviKvsObjectFunctionCall *c); + bool removeItem(KviKvsObjectFunctionCall *c); + bool count(KviKvsObjectFunctionCall *c); + bool currentText(KviKvsObjectFunctionCall *c); + bool currentItem(KviKvsObjectFunctionCall *c); + bool textAt(KviKvsObjectFunctionCall *c); + bool setCurrentItem(KviKvsObjectFunctionCall *c); + bool clear(KviKvsObjectFunctionCall *c); + bool setSelectionMode(KviKvsObjectFunctionCall *c); + bool selectionMode(KviKvsObjectFunctionCall *c); + bool insertWidgetItem(KviKvsObjectFunctionCall *c); + bool isSelected(KviKvsObjectFunctionCall *c); + bool setSelected(KviKvsObjectFunctionCall *c); + bool setFlags(KviKvsObjectFunctionCall *c); + bool selectedItems(KviKvsObjectFunctionCall *c); + bool setForeground(KviKvsObjectFunctionCall *c); + bool setIcon(KviKvsObjectFunctionCall *c); + bool setChecked(KviKvsObjectFunctionCall *c); + bool setFont(KviKvsObjectFunctionCall *c); + bool isChecked(KviKvsObjectFunctionCall *c); + bool itemAt(KviKvsObjectFunctionCall *c); + bool itemRect(KviKvsObjectFunctionCall *c); + + // events + bool currentItemChangedEvent(KviKvsObjectFunctionCall *c); + bool itemChangedEvent(KviKvsObjectFunctionCall *c); + bool itemEnteredEvent(KviKvsObjectFunctionCall *c); + +protected slots: + void selectionChanged(); + void currentItemChanged(QListWidgetItem *,QListWidgetItem *); + void slotItemEntered(QListWidgetItem *item); + void slotItemChanged(QListWidgetItem *item); + +}; + + +#endif // !_CLASS_COMBOBOX_H_ diff --git a/src/modules/objects/KvsObject_mainWindow.cpp b/src/modules/objects/KvsObject_mainWindow.cpp new file mode 100644 index 000000000..71844c67a --- /dev/null +++ b/src/modules/objects/KvsObject_mainWindow.cpp @@ -0,0 +1,101 @@ +//============================================================================= +// +// File : KvsObject_mainWindow.cpp +// Creation date : Mon Feb 28 14:21:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviTalMainWindow.h" +#include "KvsObject_mainWindow.h" +#include "KviError.h" +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KviIconManager.h" + + +/* + @doc: mainwindow + @keyterms: + mainwindow object class, + @title: + mainwindow class + @type: + class + @short: + Provides a mainwindow. + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + The mainwindow class provides a main application window, with menubar, toolbars. + @functions: + !fn: $setCentralWidget() + Sets the central widget for the main window to . +*/ + +KVSO_BEGIN_REGISTERCLASS(KvsObject_mainWindow,"mainwindow","widget") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_mainWindow,setCentralWidget) + +KVSO_END_REGISTERCLASS(KvsObject_mainWindow) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_mainWindow,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_mainWindow) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_mainWindow) + +KVSO_END_CONSTRUCTOR(KvsObject_mainWindow) + +bool KvsObject_mainWindow::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + setObject(new KviTalMainWindow(parentScriptWidget(), getName().toUtf8().data()), true); + return true; +} + +KVSO_CLASS_FUNCTION(mainWindow,setCentralWidget) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsObject * pObject; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + if (!pObject) + { + c->warning(__tr2qs_ctx("Widget parameter is not an object","objects")); + return true; + } + if (!pObject->object()) + { + c->warning(__tr2qs_ctx("Widget parameter is not a valid object","objects")); + return true; + } + if(!pObject->inheritsClass("widget")) + { + c->warning(__tr2qs_ctx("Widget object required","objects")); + return TRUE; + } + ((KviTalMainWindow *)widget())->setCentralWidget(((QWidget *)(pObject->object()))); + return true; +} + diff --git a/src/modules/objects/KvsObject_mainWindow.h b/src/modules/objects/KvsObject_mainWindow.h new file mode 100644 index 000000000..11ad34645 --- /dev/null +++ b/src/modules/objects/KvsObject_mainWindow.h @@ -0,0 +1,46 @@ +#ifndef _CLASS_MAINWINDOW_H_ +#define _CLASS_MAINWINDOW_H_ +//============================================================================= +// +// File : KvsObject_mainWindow.h +// Creation date : Mon Feb 28 14:21:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include "KvsObject_widget.h" +#include "object_macros.h" + +class KvsObject_mainWindow : public KvsObject_widget +{ +public: + KVSO_DECLARE_OBJECT(KvsObject_mainWindow) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool setCentralWidget(KviKvsObjectFunctionCall *c); +}; + + +#endif //!_CLASS_MAINWINDOW_H_ + diff --git a/src/modules/objects/KvsObject_memoryBuffer.cpp b/src/modules/objects/KvsObject_memoryBuffer.cpp new file mode 100644 index 000000000..e5947f448 --- /dev/null +++ b/src/modules/objects/KvsObject_memoryBuffer.cpp @@ -0,0 +1,125 @@ +//============================================================================= +// +// File : KvsObject_memoryBuffer.cpp +// Creation date : Fri Mar 18 21:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_memoryBuffer.h" + +#include "KviError.h" +#include "kvi_debug.h" +#include "kvi_settings.h" +#include "KviLocale.h" +#include "QProcess" +#include "KviFileUtils.h" +#include "KviFile.h" + +#include + +/* + @doc: memorybuffer + @keyterms: + object class + @title: + memorybuffer class + @type: + class + @short: + A class container to manage binary data. + @inherits: + [class]object[/class] + @description: + The memorybuffer class is used to storage binary data[br] + @functions: + !fn: $loadFromFile() + Load into memorybuffer the file. + !fn: $saveToFile() + Save the memorybuffer to file. + +*/ + +KVSO_BEGIN_REGISTERCLASS(KvsObject_memoryBuffer,"memorybuffer","object") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_memoryBuffer,loadFromFile); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_memoryBuffer,saveToFile); +KVSO_END_REGISTERCLASS(KvsObject_memoryBuffer) + + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_memoryBuffer,KviKvsObject) + + m_pBuffer = new QByteArray(); + +KVSO_END_CONSTRUCTOR(KvsObject_memoryBuffer) + +KVSO_BEGIN_DESTRUCTOR(KvsObject_memoryBuffer) + + delete m_pBuffer; + +KVSO_END_CONSTRUCTOR(KvsObject_memoryBuffer) + +KVSO_CLASS_FUNCTION(memoryBuffer,loadFromFile) +{ + CHECK_INTERNAL_POINTER(m_pBuffer) + QString szFileName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("filename",KVS_PT_NONEMPTYSTRING,0,szFileName) + KVSO_PARAMETERS_END(c) + if(KviFileUtils::fileExists(szFileName)) + { + + KviFile f(szFileName); + qDebug("loading file %s",szFileName.toUtf8().data()); + if (f.open(QIODevice::ReadOnly)) + { + m_pBuffer->resize(f.size()); + f.read(m_pBuffer->data(),f.size()); + f.close(); + } + else qDebug("Error in load file!"); + } + else c->warning(__tr2qs_ctx("The file '%Q' does not exist","objects"),&szFileName); + return true; +} +KVSO_CLASS_FUNCTION(memoryBuffer,saveToFile) +{ + CHECK_INTERNAL_POINTER(m_pBuffer) + QString szFileName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("filename",KVS_PT_NONEMPTYSTRING,0,szFileName) + KVSO_PARAMETERS_END(c) + KviFile f(szFileName); + if (f.open(QIODevice::WriteOnly)) + { + f.write(m_pBuffer->data(),m_pBuffer->size()); + f.close(); + } + else + { + c->warning(__tr2qs_ctx("Cannot open file '%Q' for writing","objects"),&szFileName); + } + return true; +} +/* +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_memoryBuffer.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES*/ + + diff --git a/src/modules/objects/KvsObject_memoryBuffer.h b/src/modules/objects/KvsObject_memoryBuffer.h new file mode 100644 index 000000000..0cd6fd388 --- /dev/null +++ b/src/modules/objects/KvsObject_memoryBuffer.h @@ -0,0 +1,53 @@ +#ifndef _CLASS_MEMORYBUFFER_H_ +#define _CLASS_MEMORYBUFFER_H_ +//============================================================================= +// +// File : KvsObject_memoryBuffer.h +// Creation date : Fri Mar 18 21:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include + +#include "object_macros.h" + + + +class KvsObject_memoryBuffer : public KviKvsObject +{ +public: + KVSO_DECLARE_OBJECT(KvsObject_memoryBuffer) +protected: + QByteArray * m_pBuffer; +public: + QByteArray dataBuffer() + { + return *m_pBuffer; + }; + QByteArray *pBuffer() + { + return m_pBuffer; + }; + bool loadFromFile(KviKvsObjectFunctionCall *c); + bool saveToFile(KviKvsObjectFunctionCall *c); +}; + +#endif // !_CLASS_MEMORYBUFFER_H_ diff --git a/src/modules/objects/KvsObject_menuBar.cpp b/src/modules/objects/KvsObject_menuBar.cpp new file mode 100644 index 000000000..0a9904b2a --- /dev/null +++ b/src/modules/objects/KvsObject_menuBar.cpp @@ -0,0 +1,77 @@ +//============================================================================= +// +// File : KvsObject_menuBar.cpp +// Creation date : Tue Now 26 13:16:59 CEST 2002 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include "KvsObject_menuBar.h" +#include "KviError.h" +#include "kvi_debug.h" +#include "KviLocale.h" + +/* + @doc: menubar + @title: + menubar class + @type: + class + @short: + A menu bar object implementation + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + + @functions: + !fn: $insertItem() + Returns an integer that identifies the inserted item. +*/ + +KVSO_BEGIN_REGISTERCLASS(KvsObject_menuBar,"menubar","widget") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_menuBar,insertItem) +KVSO_END_REGISTERCLASS(KvsObject_menuBar) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_menuBar,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_menuBar) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_menuBar) + +KVSO_END_CONSTRUCTOR(KvsObject_menuBar) + +bool KvsObject_menuBar::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + SET_OBJECT(QMenuBar) + return true; +} + +KVSO_CLASS_FUNCTION(menuBar,insertItem) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szItem; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("item",KVS_PT_STRING,0,szItem) + KVSO_PARAMETERS_END(c) + ((QMenuBar *)widget())->addAction(szItem); + return true; +} diff --git a/src/modules/objects/KvsObject_menuBar.h b/src/modules/objects/KvsObject_menuBar.h new file mode 100644 index 000000000..64e9b62fb --- /dev/null +++ b/src/modules/objects/KvsObject_menuBar.h @@ -0,0 +1,42 @@ +#ifndef _CLASS_MENUBAR_H_ +#define _CLASS_MENUBAR_H_ +//============================================================================= +// +// File : KvsObject_menuBar.h +// Creation date : Tue Now 26 13:15:48 CEST 2002 by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include +#include "KvsObject_widget.h" +#include "object_macros.h" + +class KvsObject_menuBar : public KvsObject_widget +{ +public: + KVSO_DECLARE_OBJECT(KvsObject_menuBar) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool insertItem(KviKvsObjectFunctionCall *c); +}; +#endif // !_CLASS_MENUBAR_H_ diff --git a/src/modules/objects/KvsObject_multiLineEdit.cpp b/src/modules/objects/KvsObject_multiLineEdit.cpp new file mode 100644 index 000000000..e7df905e5 --- /dev/null +++ b/src/modules/objects/KvsObject_multiLineEdit.cpp @@ -0,0 +1,785 @@ +//============================================================================= +// +// File : KvsObject_multiLineEdit.cpp +// Creation date : Mon Feb 19 2000 00:45:34 CET by Krzysztof Godlewski +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000 Krzysztof Godlewski +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviError.h" +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KviMemory.h" + +#include +#include +#include +#include +#include +#include + +#include "KvsObject_multiLineEdit.h" + +/* + @doc: multilineedit + @keyterms: + multilineedit object class, line editor, input + @title: + multilineedit class + @type: + class + @short: + An editor for inputting larger portions of text + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + This is class an editor for inputting larger portions of text. + Besides that, it has unfinished docs. + @functions: + !fn: $textLine() + Returns the string at line . Note that it can be an empty + string. + !fn: $numLines() + Returns number of lines in the widget. + !fn: $cursorPosition() + Returns current cursor position in ", " format. + !fn: $setReadOnly() + Sets the editor to be read-only if bReadOnly is 1 or + removes the read-only status is ReadOnly is 0 + !fn: $atBeginning() + Returns 1(TRUE) if the cursor is placed at the beginning of the text; otherwise returns 0(FALSE). + !fn: $atEnd() + Returns 1(TRUE) if the cursor is placed at the end of the text; otherwise returns 0(FALSE). + !fn: $setWordWrap() + Sets the word wrap mode to mode. Valid Values are:[br] + - NoWrap - Do not wrap the text.[br] + - WidgetWidth - Wrap the text at the current width of the widget.[br] + - FixedPixelWidth - Wrap the text at a fixed number of pixels from the widget's left side.[br] + - FixedColumnWidth - Wrap the text at a fixed number of character columns from the widget's left side. + !fn: $wordWrap() + Returns the word wrap mode. NoWrap, WidgetWidth, FixedPixelWidth, FixedColumnWidth. + !fn: $text() + Returns the multiline edit's text. + !fn: $length() + Returns the number of characters in the text This function ignores newlines. + !fn: $setMaxLines() + Sets the max number of the lines to + !fn: $maxLines() + Returns the max number of the lines in the multiline edit. + !fn: $insert() + Inserts text at the current cursor position. + !fn: $append() + Appends a new paragraph with text to the end of the multiline edit. + !fn: $copy() + Copies any selected text from selection to the clipboard. + !fn: $cut() + Copies the selected text from selection to the clipboard and deletes it from the multiline edit. + !fn: $paste() + Pastes the text from the clipboard into the multiline edit at the current cursor position. + !fn: $setFamily() + Sets the font family of the current format to fontFamily. + !fn: $setItalic() + If the bool value is 1 sets the current format to italic; otherwise, if it's 0 sets the current format to no-italic. + !fn: $setBold() + If the bool value is 1 sets the current format to bold; otherwise, if it's 0 sets the current format to no-bold. + !fn: $setUnderline() + If the bool value is 1 sets the current format to underline; otherwise, if it's 0 sets the current format to no-underline. + !fn: $italic() + Returns 1(TRUE) if the current format is italic; otherwise returns 0(FALSE). + !fn: $bold() + Returns 1(TRUE) if the current format is bold; otherwise returns 0(FALSE). + !fn: $underline() + Returns 1(TRUE) if the current format is underline; otherwise returns 0(FALSE). + !fn: $zoomIn() + Zooms in on the text by making the base font size range points larger. + !fn: $zoomOut() + Zooms out on the text by making the base font size range points smaller. + !fn: $undo() + Undoes the last operation. + !fn: $redo() + Redoes the last operation. + !fn: $clear() + Deletes all the text in the multiline edit. + !fn: $setUndoRedoEnabled() + Sets whether undo/redo is enabled to the bool value. + !fn: $isUndoRedoEnabled() + Returns 1 (TRUE) if undo/redo is enabled; otherwise returns 0 (FALSE). + !fn: $undoDepth() + Returns the depth of the undo history. + !fn: $setText() + Sets the text edit's text to txt. + !fn: $setColor() + Sets the foreground color of this widget to :valid values are: + -hex string: must be a string with 6 hexadecimal digits (like the ones used to + specify colors in html pages). The first two digits specify + the RED component, the third and fourth digit specify the GREEN component + and the last two specify the BLUE component. + -array(red:integer,green:integer,blue:integer) + -red:integer,green:integer,blue:integer. + !fn: $setPointSize() + Sets to 1 if you want that hypertext links will be underlined; otherwise sets to 0. + !fn: $setTextFormat() + Sets the text format. Correct values are RichText, PlainText. + !fn: $textFormat() + Returns the text format: rich text or plain text. + !fn: $loadFile() + Load the file specified in the , also html files. + !fn: $isUndoAvailable () + Returns 1(TRUE) if undo is available; otherwise returns 0(FALSE). + !fn: $isRedoAvailable () + Returns 1(TRUE) if redo is available; otherwise returns 0(FALSE). + !fn: $lines() + Returns the number of lines in the multilineedit. + !fn: $lineOfChar(,) + Returns the line number of the line in paragraph par in which the character at position index appears.[br] + If there is no such paragraph or no such character at the index position -1 is returned. + !fn: $setModified() + Sets whether the document has been modified by the user. Valid Values are 1(TRUE) or 0(FALSE) + !fn: $setAlignment() + Sets the alignment of the current paragraph to . Valid values are:[br] + - Auto - Aligns according to the language.[b + - Left - Aligns with the left edge.[br] + - Right - Aligns with the right edge.[br] + - Center - Centers in both dimensions. + - Justify - Justify the text. + */ + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_textedit,"multilineedit","widget") + + KVSO_REGISTER_HANDLER(KvsObject_textedit,"textLine", functionTextLine) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"setWordWrap", functionSetWordWrap) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"wordWrap", functionWordWrap) + + KVSO_REGISTER_HANDLER(KvsObject_textedit,"atEnd", functionAtEnd) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"numLines", functionNumLines) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"atBeginning", functionAtBeginning) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"cursorPosition", functionCursorPosition) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"text", functionText) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"insert", functionInsert) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"maxLines", functionMaxLines) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"setMaxLines", functionSetMaxLines) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"append", functionAppend) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"copy", functionCopy) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"cut", functionCut) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"paste", functionPaste) + + //->Set Style + KVSO_REGISTER_HANDLER(KvsObject_textedit,"setFamily", functionsetFamily) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"setItalic", functionsetItalic) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"setBold", functionsetBold) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"setUnderline", functionsetUnderline) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"italic", functionitalic) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"bold", functionbold) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"underline", functionunderline) + + //->Zoom In, Out, To + KVSO_REGISTER_HANDLER(KvsObject_textedit,"zoomIn", functionzoomIn) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"zoomOut", functionzoomOut) + + //->Undo & Redo + KVSO_REGISTER_HANDLER(KvsObject_textedit,"undo", functionundo) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"redo", functionredo) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"clear", functionclear) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"setUndoRedoEnabled", functionsetUndoRedoEnabled) + + + KVSO_REGISTER_HANDLER(KvsObject_textedit,"isUndoRedoEnabled", functionisUndoRedoEnabled) + + //->Text color & others + KVSO_REGISTER_HANDLER(KvsObject_textedit,"setText", functionsetText) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"setColor", functionsetColor) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"setModified", functionsetModified) + + KVSO_REGISTER_HANDLER(KvsObject_textedit,"setPointSize", functionsetPointSize) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"setReadOnly",functionSetReadOnly) + + KVSO_REGISTER_HANDLER(KvsObject_textedit,"setTextFormat", functionsetTextFormat) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"textFormat", functiontextFormat) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"loadFile", functionloadFile); + KVSO_REGISTER_HANDLER(KvsObject_textedit,"setAlignment", functionsetAlignment) + + KVSO_REGISTER_HANDLER(KvsObject_textedit,"lines", functionlines) + KVSO_REGISTER_HANDLER(KvsObject_textedit,"selectAll", functionselectAll) +KVSO_END_REGISTERCLASS(KvsObject_textedit) + + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_textedit,KvsObject_widget) + + +KVSO_END_CONSTRUCTOR(KvsObject_textedit) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_textedit) + +KVSO_END_CONSTRUCTOR(KvsObject_textedit) + +bool KvsObject_textedit::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + SET_OBJECT(QTextEdit); + return true; +} + + + +bool KvsObject_textedit::functionSetReadOnly(KviKvsObjectFunctionCall * c) +{ + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + if(widget()) + ((QTextEdit *)widget())->setReadOnly(bEnabled); + return true; +} + +bool KvsObject_textedit::functionTextLine(KviKvsObjectFunctionCall * c) +{ + kvs_int_t iBlock; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("line",KVS_PT_INT,0,iBlock) + KVSO_PARAMETERS_END(c) + if(!widget())return true; + if(iBlock > ((QTextEdit *)widget())->document()->blockCount() || iBlock < 0) c->warning(__tr2qs_ctx("No such line '%d'","objects"),&iBlock); + else + c->returnValue()->setString(((QTextEdit *)widget())->document()->findBlockByNumber(iBlock).text()); + + return true; +} +bool KvsObject_textedit::functionNumLines(KviKvsObjectFunctionCall * c) +{ + if(widget()) c->returnValue()->setInteger(((QTextEdit *)widget())->document()->blockCount()); + return true; +} +bool KvsObject_textedit::functionCursorPosition(KviKvsObjectFunctionCall * c) +{ + if(!widget()) return true; + int iRow=((QTextEdit *)widget())->textCursor().blockNumber(); + int iCol=((QTextEdit *)widget())->textCursor().columnNumber(); + + KviKvsArray * a = new KviKvsArray(); + a->set(0,new KviKvsVariant((kvs_int_t)iRow)); + a->set(1,new KviKvsVariant((kvs_int_t)iCol)); + c->returnValue()->setArray(a); + return true; +} + +bool KvsObject_textedit::functionAtBeginning(KviKvsObjectFunctionCall * c) +{ + if(!widget()) return true; + c->returnValue()->setBoolean(((QTextEdit *)widget())->textCursor().atStart()); + return true; +} + +bool KvsObject_textedit::functionAtEnd(KviKvsObjectFunctionCall * c) +{ + if(!widget()) return true; + c->returnValue()->setBoolean(((QTextEdit *)widget())->textCursor().atEnd()); + return true; +} + +bool KvsObject_textedit::functionSetWordWrap(KviKvsObjectFunctionCall * c) +{ + if(!widget())return true; + QString szWrap; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("word_wrap",KVS_PT_STRING,0,szWrap) + KVSO_PARAMETERS_END(c) + + if(KviQString::equalCI(szWrap,"NoWrap")) + ((QTextEdit *)widget())->setLineWrapMode(QTextEdit::NoWrap); + else if(KviQString::equalCI(szWrap,"WidgetWidth")) + ((QTextEdit *)widget())->setLineWrapMode(QTextEdit::WidgetWidth); + else if(KviQString::equalCI(szWrap,"FixedPixelWidth")) + ((QTextEdit *)widget())->setLineWrapMode(QTextEdit::FixedPixelWidth); + else if(KviQString::equalCI(szWrap,"FixedColumnWidth")) + ((QTextEdit *)widget())->setLineWrapMode(QTextEdit::FixedColumnWidth); + else c->warning(__tr2qs_ctx("Unknown word wrap '%Q'","objects"),&szWrap); + return true; +} + + +bool KvsObject_textedit::functionWordWrap(KviKvsObjectFunctionCall *c) +{ + + if(!widget()) return true; + QTextEdit::LineWrapMode mode=((QTextEdit *)widget())->lineWrapMode(); + QString szWrapMode; + if (mode==QTextEdit::NoWrap) szWrapMode="NoWrap"; + else if (mode==QTextEdit::WidgetWidth) szWrapMode="WidgetWidth"; + else if (mode==QTextEdit::FixedPixelWidth) szWrapMode="FixedPixelWidth"; + else szWrapMode="FixedColumnWidth"; + c->returnValue()->setString(szWrapMode); + + return true; +} + +bool KvsObject_textedit::functionText(KviKvsObjectFunctionCall * c) +{ + if(widget()) + c->returnValue()->setString(((QTextEdit *)widget())->document()->toPlainText()); + return true; +} + +bool KvsObject_textedit::functionSetMaxLines(KviKvsObjectFunctionCall * c) +{ + kvs_uint_t imaxLines; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("max_lines",KVS_PT_UNSIGNEDINTEGER,0,imaxLines) + KVSO_PARAMETERS_END(c) + if(widget()) + ((QTextEdit *)widget())->document()->setMaximumBlockCount(imaxLines); + return true; +} + +bool KvsObject_textedit::functionMaxLines(KviKvsObjectFunctionCall * c) +{ + if(widget()) + c->returnValue()->setInteger(((QTextEdit *)widget())->document()->maximumBlockCount()); + return true; +} + +bool KvsObject_textedit::functionInsert(KviKvsObjectFunctionCall * c) +{ + QString szInsert; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szInsert) + KVSO_PARAMETERS_END(c) + if (widget()) + { + QTextCursor cursor=((QTextEdit *)widget())->textCursor(); + cursor.insertText(szInsert); + ((QTextEdit *)widget())->setTextCursor(cursor); + } + return true; +} + +bool KvsObject_textedit::functionAppend(KviKvsObjectFunctionCall * c) +{ + QString szAppend; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szAppend) + KVSO_PARAMETERS_END(c) + if (widget()) + ((QTextEdit *)widget())->append(szAppend); + return true; +} + +bool KvsObject_textedit::functionCopy(KviKvsObjectFunctionCall *) +{ + if(widget()) + ((QTextEdit *)widget())->copy(); + return true; +} + +bool KvsObject_textedit::functionCut(KviKvsObjectFunctionCall *) +{ + if(widget()) + ((QTextEdit *)widget())->cut(); + return true; +} + +bool KvsObject_textedit::functionPaste(KviKvsObjectFunctionCall *) +{ + if(widget()) + ((QTextEdit *)widget())->paste(); + return true; +} + +//->Set Bold, Italic, Underline +bool KvsObject_textedit::functionsetBold(KviKvsObjectFunctionCall * c) +{ + bool bFlag; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bBold",KVS_PT_BOOL,0,bFlag) + KVSO_PARAMETERS_END(c) + if (widget()) + ((QTextEdit *)widget())->setFontWeight(bFlag?QFont::Bold:QFont::Normal); + return true; +} + +bool KvsObject_textedit::functionsetUnderline(KviKvsObjectFunctionCall * c) +{ + bool bFlag; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bUnderline",KVS_PT_BOOL,0,bFlag) + KVSO_PARAMETERS_END(c) + if (widget()) + ((QTextEdit *)widget())->setFontUnderline(bFlag); + return true; +} + +bool KvsObject_textedit::functionsetItalic(KviKvsObjectFunctionCall * c) +{ + bool bFlag; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bItalic",KVS_PT_BOOL,0,bFlag) + KVSO_PARAMETERS_END(c) + if (widget()) + ((QTextEdit *)widget())->setFontItalic(bFlag); + return true; +} + +//-->Returns Italic, Bold, Underline. +bool KvsObject_textedit::functionbold(KviKvsObjectFunctionCall * c) +{ + if(widget()) + c->returnValue()->setBoolean(((QTextEdit *)widget())->fontWeight() >= QFont::Bold ); + return true; +} + +bool KvsObject_textedit::functionitalic(KviKvsObjectFunctionCall * c) +{ + if(widget()) + c->returnValue()->setBoolean(((QTextEdit *)widget())->fontItalic()); + return true; +} + +bool KvsObject_textedit::functionunderline(KviKvsObjectFunctionCall * c) +{ + if(widget()) + c->returnValue()->setBoolean(((QTextEdit *)widget())->fontUnderline()); + return true; +} + +//->Zoom In, out at +bool KvsObject_textedit::functionzoomIn(KviKvsObjectFunctionCall * c) +{ + kvs_int_t iZoom; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("zoom_value",KVS_PT_INT,KVS_PF_OPTIONAL,iZoom) + KVSO_PARAMETERS_END(c) + if (!widget()) return true; + if (!iZoom) + ((QTextEdit *)object())->zoomIn(); + else + ((QTextEdit *)object())->zoomIn(iZoom); + return true; +} + +bool KvsObject_textedit::functionzoomOut(KviKvsObjectFunctionCall * c) +{ + kvs_int_t iZoom; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("zoom_value",KVS_PT_INT,KVS_PF_OPTIONAL,iZoom) + KVSO_PARAMETERS_END(c) + if (!widget()) return true; + if (!iZoom) + ((QTextEdit *)object())->zoomOut(); + else + ((QTextEdit *)object())->zoomOut(iZoom); + return true; +} + + + +//-> Undo & Redo functions +bool KvsObject_textedit::functionundo(KviKvsObjectFunctionCall *) +{ + if(widget()) + ((QTextEdit *)widget())->undo(); + return true; +} + +bool KvsObject_textedit::functionredo(KviKvsObjectFunctionCall *) +{ + if(widget()) + ((QTextEdit *)widget())->redo(); + return true; +} + +bool KvsObject_textedit::functionclear(KviKvsObjectFunctionCall *) +{ + if(widget()) + ((QTextEdit *)widget())->clear(); + return true; +} + + + +bool KvsObject_textedit::functionsetUndoRedoEnabled(KviKvsObjectFunctionCall * c) +{ + bool bFlag; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bUndoredo",KVS_PT_BOOL,0,bFlag) + KVSO_PARAMETERS_END(c) + if (widget()) + ((QTextEdit *)widget())->setUndoRedoEnabled(bFlag); + return true; +} + +bool KvsObject_textedit::functionisUndoRedoEnabled(KviKvsObjectFunctionCall * c) +{ + if(widget()) + c->returnValue()->setBoolean(((QTextEdit *)widget())->isUndoRedoEnabled()); + return true; +} + + +//-->Text & Color & Family +bool KvsObject_textedit::functionsetText(KviKvsObjectFunctionCall * c) +{ + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETERS_END(c) + if (widget()) + ((QTextEdit *)widget())->setText(szText); + return true; +} + +bool KvsObject_textedit::functionsetPlainText(KviKvsObjectFunctionCall * c) +{ + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETERS_END(c) + if (widget()) + ((QTextEdit *)widget())->setPlainText(szText); + return true; +} + +bool KvsObject_textedit::functionsetHtmlText(KviKvsObjectFunctionCall * c) +{ + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETERS_END(c) + if (widget()) + ((QTextEdit *)widget())->setHtml(szText); + return true; +} + +bool KvsObject_textedit::functionsetColor(KviKvsObjectFunctionCall * c) +{ + KviKvsVariant * pColArray; + kvs_int_t iColR,iColG,iColB; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("red_or_array",KVS_PT_VARIANT,0,pColArray) + KVSO_PARAMETER("green",KVS_PT_INT,KVS_PF_OPTIONAL,iColG) + KVSO_PARAMETER("blue",KVS_PT_INT,KVS_PF_OPTIONAL,iColB) + KVSO_PARAMETERS_END(c) + if(pColArray->isArray()) + { + if(pColArray->array()->size() < 3) + { + c->error(__tr2qs_ctx("The array passed as parameter must contain at least 3 elements","objects")); + return false; + } + KviKvsVariant * pColR = pColArray->array()->at(0); + KviKvsVariant * pColG = pColArray->array()->at(1); + KviKvsVariant * pColB = pColArray->array()->at(2); + + if(!(pColR && pColG && pColB)) + { + c->error(__tr2qs_ctx("One of the colors array parameters is empty","objects")); + return false; + } + if(!(pColR->asInteger(iColR) && pColG->asInteger(iColG) && pColB->asInteger(iColB))) + { + c->error(__tr2qs_ctx("One of the colors array parameters didn't evaluate to an integer","objects")); + return false; + } + + } else { + if (c->params()->count()==1) + { + bool bOk,bOk1,bOk2; + QString value; + pColArray->asString(value); + if (value.length()!=6) + { + c->warning(__tr2qs_ctx("A string of 6 hex digits is required","objects")); + return true; + } + QString buffer(value.mid(0,2)); + iColR=buffer.toInt(&bOk,16); + buffer=value.mid(2,2); + iColG=buffer.toInt(&bOk1,16); + buffer=value.mid(4,2); + iColB=buffer.toInt(&bOk2,16); + if (!bOk || !bOk1 || !bOk2) + { + c->warning(__tr2qs_ctx("Not an hex digit","objects")); + return true; + } + if (widget()) ((QTextEdit *)widget())->setTextColor(QColor(iColR,iColG,iColB)); + return true; + } + if(c->params()->count() < 3) + { + c->error(__tr2qs_ctx("$setColor requires either an array as first parameter or three integers","objects")); + return false; + } + if(!pColArray->asInteger(iColR)) + { + c->error(__tr2qs_ctx("The first parameter didn't evaluate to an array nor an integer","objects")); + return false; + } + } + if (widget()) ((QTextEdit *)widget())->setTextColor(QColor(iColR,iColG,iColB)); + return true; +} + +bool KvsObject_textedit::functionsetPointSize(KviKvsObjectFunctionCall * c) +{ + kvs_real_t dPointSize; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("point_size",KVS_PT_REAL,0,dPointSize) + KVSO_PARAMETERS_END(c) + if (widget()) + ((QTextEdit *)widget())->setFontPointSize(dPointSize); + return true; +} + + + +bool KvsObject_textedit::functionsetFamily(KviKvsObjectFunctionCall * c) +{ + QString szFamily; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("family",KVS_PT_STRING,0,szFamily) + KVSO_PARAMETERS_END(c) + if (widget()) + ((QTextEdit *)widget())->setFontFamily(szFamily); + return true; +} + +bool KvsObject_textedit::functionsetModified(KviKvsObjectFunctionCall * c) +{ + bool bFlag; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bModified",KVS_PT_BOOL,0,bFlag) + KVSO_PARAMETERS_END(c) + if (widget()) + ((QTextEdit *)widget())->document()->setModified(bFlag); + return true; +} + +bool KvsObject_textedit::functionModified(KviKvsObjectFunctionCall * c) +{ + if(widget()) + c->returnValue()->setBoolean(((QTextEdit *)widget())->document()->isModified()); + return true; +} + + +bool KvsObject_textedit::functiontextFormat(KviKvsObjectFunctionCall *c) +{ + if(!widget())return true; + if(((QTextEdit *)widget())->acceptRichText()) + c->returnValue()->setString(QString("RichText")); + else + c->returnValue()->setString(QString("PlainText")); + return true; +} + +bool KvsObject_textedit::functionsetTextFormat(KviKvsObjectFunctionCall * c) +{ + QString szFormat; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("textformat",KVS_PT_STRING,0,szFormat) + KVSO_PARAMETERS_END(c) + if(!widget()) return true; + if(KviQString::equalCI(szFormat,"PlainText")) + ((QTextEdit *)widget())->setAcceptRichText(false); + else if(KviQString::equalCI(szFormat,"RichText")) + ((QTextEdit *)widget())->setAcceptRichText(true); + else c->warning(__tr2qs_ctx("Unknown text format '%Q'","objects"),&szFormat); + return true; +} + + + + +bool KvsObject_textedit::functionloadFile(KviKvsObjectFunctionCall * c) +{ + QString szFile; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("file_name",KVS_PT_STRING,0,szFile) + KVSO_PARAMETERS_END(c) + if ( !QFile::exists(szFile)) + { + c->warning(__tr2qs_ctx("I can't find the specified file '%Q'.","objects"),&szFile); + return true; + } + + QFile file( szFile ); + if ( !file.open( QIODevice::ReadOnly ) ) + { + c->warning(__tr2qs_ctx("I cannot read the file '%Q'.","objects"),&szFile); + return true; + } + + QTextStream ts( &file ); + QString txt = ts.readAll(); + //settext tries to understand if the text is html or plain + ((QTextEdit *)widget())->setText( txt ); + + file.close(); + return true; +} + +bool KvsObject_textedit::functionsetAlignment(KviKvsObjectFunctionCall * c) +{ + QString szAlignment; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("alignment",KVS_PT_STRING,0,szAlignment) + KVSO_PARAMETERS_END(c) + if(!widget()) return true; + if(KviQString::equalCI(szAlignment,"Left")) + ((QTextEdit *)widget())->setAlignment(Qt::AlignLeft); + else if(KviQString::equalCI(szAlignment,"Right")) + ((QTextEdit *)widget())->setAlignment(Qt::AlignRight); + else if(KviQString::equalCI(szAlignment,"Center")) + ((QTextEdit *)widget())->setAlignment(Qt::AlignCenter); + else if(KviQString::equalCI(szAlignment,"Justify")) + ((QTextEdit *)widget())->setAlignment(Qt::AlignJustify); + else c->warning(__tr2qs_ctx("Unknown alignment '%Q'","objects"),&szAlignment); + return true; +} + + + + +bool KvsObject_textedit::functionlines(KviKvsObjectFunctionCall * c) +{ + if(widget()) + c->returnValue()->setInteger(((QTextEdit *)widget())->document()->blockCount()); + return true; +} + + + + +bool KvsObject_textedit::functionselectAll(KviKvsObjectFunctionCall *) +{ + if (widget()) + ((QTextEdit *)widget())->selectAll(); + return true; +} + + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_multiLineEdit.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/objects/KvsObject_multiLineEdit.h b/src/modules/objects/KvsObject_multiLineEdit.h new file mode 100644 index 000000000..aa264331a --- /dev/null +++ b/src/modules/objects/KvsObject_multiLineEdit.h @@ -0,0 +1,93 @@ +#ifndef _CLASS_MULTILINEEDIT_H_ +#define _CLASS_MULTILINEEDIT_H_ +//============================================================================= +// +// File : KvsObject_multiLineEdit.cpp +// Creation date : Mon Feb 19 2000 00:45:34 CET by Krzysztof Godlewski +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000 Krzysztof Godlewski +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include "KvsObject_widget.h" +#include "object_macros.h" + +class KvsObject_textedit : public KvsObject_widget +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_textedit) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + bool functionTextLine(KviKvsObjectFunctionCall *c); + bool functionInsertLine(KviKvsObjectFunctionCall *c); + bool functionRemoveLine(KviKvsObjectFunctionCall *c); + bool functionNumLines(KviKvsObjectFunctionCall *c); + bool functionAtBeginning(KviKvsObjectFunctionCall *c); + bool functionAtEnd(KviKvsObjectFunctionCall *c); + bool functionSetWordWrap(KviKvsObjectFunctionCall *c); + bool functionWordWrap(KviKvsObjectFunctionCall *c); + bool functionCursorPosition(KviKvsObjectFunctionCall *c); + bool functionText(KviKvsObjectFunctionCall *c); + bool functionLength(KviKvsObjectFunctionCall *c); + bool functionSetMaxLines(KviKvsObjectFunctionCall *c); + bool functionMaxLines(KviKvsObjectFunctionCall *c); + bool functionSetReadOnly(KviKvsObjectFunctionCall *c); + bool functionInsert(KviKvsObjectFunctionCall *c); + bool functionAppend(KviKvsObjectFunctionCall *c); + bool functionCopy(KviKvsObjectFunctionCall *c); + bool functionPaste(KviKvsObjectFunctionCall *c); + bool functionCut(KviKvsObjectFunctionCall *c); + bool functionsetItalic(KviKvsObjectFunctionCall *c); + bool functionitalic(KviKvsObjectFunctionCall *c); + bool functionsetBold(KviKvsObjectFunctionCall *c); + bool functionbold(KviKvsObjectFunctionCall *c); + bool functionsetUnderline(KviKvsObjectFunctionCall *c); + bool functionunderline(KviKvsObjectFunctionCall *c); + bool functionzoomIn(KviKvsObjectFunctionCall *c); + bool functionzoomOut(KviKvsObjectFunctionCall *c); + bool functionundo(KviKvsObjectFunctionCall *c); + bool functionredo(KviKvsObjectFunctionCall *c); + bool functiondel(KviKvsObjectFunctionCall *c); + bool functionclear(KviKvsObjectFunctionCall *c); + bool functionsetUndoRedoEnabled(KviKvsObjectFunctionCall *c); + bool functionisUndoRedoEnabled(KviKvsObjectFunctionCall *c); + bool functionsetText(KviKvsObjectFunctionCall *c); + bool functionsetHtmlText(KviKvsObjectFunctionCall *c); + bool functionsetPlainText(KviKvsObjectFunctionCall *c); + bool functionsetPointSize(KviKvsObjectFunctionCall *c); + bool functionsetColor(KviKvsObjectFunctionCall *c); + bool functionisUndoAvailable(KviKvsObjectFunctionCall *c); + bool functionisRedoAvailable(KviKvsObjectFunctionCall *c); + bool functionsetFamily(KviKvsObjectFunctionCall *c); + bool functionsetTextFormat(KviKvsObjectFunctionCall *c); + bool functiontextFormat(KviKvsObjectFunctionCall *c); + bool functionloadFile(KviKvsObjectFunctionCall *c); + bool functionlines(KviKvsObjectFunctionCall *c); + bool functionselectAll(KviKvsObjectFunctionCall *c); + bool functionsetModified(KviKvsObjectFunctionCall *c); + bool functionModified(KviKvsObjectFunctionCall *c); + bool functionsetAlignment(KviKvsObjectFunctionCall *c); + +}; + +#endif //!_CLASS_MULTILINEEDIT_H_ diff --git a/src/modules/objects/KvsObject_painter.cpp b/src/modules/objects/KvsObject_painter.cpp new file mode 100644 index 000000000..a73d7924e --- /dev/null +++ b/src/modules/objects/KvsObject_painter.cpp @@ -0,0 +1,1738 @@ +//============================================================================= +// +// File : KvsObject_painter.cpp +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// Lucia Papini (^ashura^) English Translation. +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_painter.h" +#include "KvsObject_pixmap.h" +#include "KvsObject_widget.h" + +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KviError.h" +#include "KviIconManager.h" +#include "KviMemory.h" + #include +#include +#include + +#define PAINTER_ROTATE(__angle,__axis)\ + QTransform transform;\ + transform.rotate(__angle,__axis);\ + m_pPainter->setTransform(transform,true); + +#define PAINTER_TRANSLATE(__x,__y)\ + QTransform transform;\ + transform.translate(__x,__y);\ + m_pPainter->setTransform(transform,true); + +#define PAINTER_SHEAR(__sH,__sV)\ + QTransform transform;\ + transform.shear(__sH,__sV);\ + m_pPainter->setTransform(transform,true); + +#define PAINTER_SCALE(__sX,__sY)\ + QTransform transform;\ + transform.scale(__sX,__sY);\ + m_pPainter->setTransform(transform,true); + + +const Qt::PenStyle penstyles_cod[] = { + Qt::NoPen, + Qt::SolidLine, + Qt::DashLine, + Qt::DotLine, + Qt::DashDotLine, + Qt::DashDotDotLine +}; + +const char * const penstyles_tbl[] = { + "noPen", + "solidLine", + "dashLine", + "dotLine", + "dashDotLine", + "dashDotDotLine" +}; + +#define penstyles_num (sizeof(penstyles_tbl) / sizeof(penstyles_tbl[0])) + +const Qt::BrushStyle brushstyles_cod[] = { + Qt::NoBrush, + Qt::SolidPattern, + Qt::Dense1Pattern, + Qt::Dense2Pattern, + Qt::Dense3Pattern, + Qt::Dense4Pattern, + Qt::Dense5Pattern, + Qt::Dense6Pattern, + Qt::Dense7Pattern, + Qt::HorPattern, + Qt::VerPattern, + Qt::CrossPattern, + Qt::BDiagPattern, + Qt::FDiagPattern, + Qt::DiagCrossPattern +}; + +const char * const brushstyles_tbl[] = { + "NoBrush", + "SolidPattern", + "Dense1Pattern", + "Dense2Pattern", + "Dense3Pattern", + "Dense4Pattern", + "Dense5Pattern", + "Dense6Pattern", + "Dense7Pattern", + "HorPattern", + "VerPattern", + "CrossPattern", + "BDiagPattern", + "FDiagPattern", + "DiagCrossPattern" +}; + +#define brushstyles_num (sizeof(brushstyles_tbl) / sizeof(brushstyles_tbl[0])) + + +/* + @doc: painter + @keyterms: + painter object class, line editor, input + @title: + painter class + @type: + class + @short: + This class provide a painter to paint line and shapes. + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + + With this class you can draw many graphics objects from simple lines to complex shapes like pies and chords.[br] + It can also draw aligned text and pixmaps. Normally, it draws in a "natural" coordinate system, but it can also do view and world transformation.[br] + The class need to be implemented into a [classfnc]$paintEvent[/classfnc](); + @functions: + !fn: $drawLine(,,,) + Draws a line from (x1, y1) to (x2, y2) and sets the current pen position to (x2, y2). + !fn: $begin() + Begins painting the paint device : the parameter MUST be a widget or a pixmap.[br] + Warning: A paint device can only be painted by one painter at a time. + !fn: $beginPdf() + Begins painting on a file using the pdf format. + At present the pdf support is in experimental state. + !fn: $end() + Ends painting. Any resources used while painting are released. + !fn: $setPen(,,][,,],[system color:RGB or HSV) + The pen defines the lines or text, color. You can set it with Red,Green,Blue, or H,S,V value[br] + All parameters are in integer form. + !fn: $setPen(,,][,,],[opacity],[system color:RGB or HSV]) + The pen defines the lines or text, color. You can set it with Red,Green,Blue, or H,S,V value[br] + All parameters are in integer form. + The HSV system, like RGB, has three components:[br] + * H, for hue, is either 0-359 if the color is chromatic (not gray), or meaningless if it is gray.[br] + It represents degrees on the color wheel familiar to most people. Red is 0 (degrees), green is 120 and blue is 240.[br] + * S, for saturation, is 0-255, and the bigger it is, the stronger the color is. Grayish colors have saturation near 0; very strong colors have saturation near 255.[br] + * V, for value, is 0-255 and represents lightness or brightness of the color. 0 is black; 255 is as far from black as possible.[br] + Examples: RED is H=0, S=255, V=255.[br] + Light RED could have H about 0, S about 50-100, and S=255. + ES: $setPen(00,00,00) for black;[br] + Default color mode is RGB; + !fn: $setBrush(,,][,,],[system color:RGB or HSV) + Sets the painter's brush to have the specified color.[br] + Example:[br] + class (wdg,widget)[br] + {[br] + paintevent()[br] + {[br] + %b=$new(painter)[br] + %b->$setBackgroundMode(Opaque)[br] + %b->$setBrush(0,250,250)[br] + %b->$begin($$)[br] + %b->$drawEllipse(50,50,100,50)[br] + }[br] + }[br] + %aa=$new(wdg)[br] + %aa->$show()[br] + !fn: $drawRect(,,,) + Draws a rectangle with upper left corner at (x, y) and with width w and height h. + !fn: $drawRoundRect(,,,,,) + Draws a rectangle with rounded corners at (x, y), with width w and height h.[rb] + The xCor and yCor arguments specify how rounded the corners should be (range is 0->99). + !fn: $drawPie(,,,,,) + Draws a pie defined by the rectangle (x, y, w, h), the start angle a and the arc length alen.[br] + The angles and are 1/16th of a degree, i.e. a full circle equals 5760 (16*360). + !fn: $drawArc(,,,,,) + Draws an arc defined by the rectangle (x, y, w, h), the start angle a and the arc length alen.[br] + The angles and are 1/16th of a degree, i.e. a full circle equals 5760 (16*360). + !fn: $drawPoint(,) + Draws a point at x and y coordinates. + !fn: $drawEllipse(,,,) + Draws an ellipse with center at (x + w/2, y + h/2) and size (w, h). + !fn: $drawChord(,,,,,) + Draws a chord defined by the rectangle (x, y, w, h), the start angle a and the arc length alen.[br] + The angles and are 1/16th of a degree, i.e. a full circle equals 5760 (16*360). + !fn: $drawText(,,,[,]) + Draws the given at position , .[br] + If is -1 (the default) all the text is drawn, otherwise the first characters are drawn. + The text's direction is given by , valid flag are:[br] + [pre] + Auto [br] + RTL (right to left) [br] + LTR (left to right) [br] + [/pre] + !fn: $drawPixmap(,,,,,,) + Draws a pixmap at x,y coordinates[br] + !fn: $setFont(,[,,,..])[br] + Set the font's family, size and style, valid flag for style are:[br] + [pre] + italic [br] + bold [br] + underline [br] + overline [br] + strikeout [br] + fixedpitch [br] + [/pre] + !fn: $setFontSize()[br] + Set the current painter font's size.[br] + !fn: $fontAscent() + Return the distance from the baseline to the highest position characters extend to. + !fn: $fontDescent() + Return the distance from the baseline to the lowest point characters extend to. + !fn: $fontMetricsWidth() + Returns the font metrics width for the painter's current font. + !fn: $fontMetricsHeight() + Returns the font metrics height for the painter's current font. + !fn: $rotate(,[]) + Rotates the coordinate system a degrees counterclockwise by the given angle about the optional parameter . + Valid values for axis are: ZAxis, XAxis, YAxis. + Optional parameter + !fn: $translate(,) + Translates the coordinate system by , . + !fn: $shear(,) + Shears the coordinate system by , . + !fn: $scale(,) + Scales the coordinate system by , . + !fn: $setBackgroundMode() + Sets the background mode of the painter to : valid values are:[br] + - Transparent (that is the default value);[br] + - Opaque.[br] + !fn: $setOpacity() + Sets the painter opacity that affects all painter operations (drawpixmap, drawtext...). Valid values range are from 0 (total transparency) to 1 (total opacity)[br] + You must invoke the [classfnc]$begin[/classfnc] before using it. + !fn: $setTextAntialiasing() + Enable/disable antialias in text if possible. + You must call the [classfnc]$begin[/classfnc] before using it. + !fn: $setAntialiasing() + Enable/disable antialias in edges of primitives if possible. + You must call the [classfnc]$begin[/classfnc] before using it. + !fn: $setSmoothPixmapTransform() + Enable/disable smooth bilinear pixmap transformation algorithm (such as bilinear). + You must call the [classfnc]$begin[/classfnc] before using it. + Example:[br] + [br] + class (hello,widget)[br] + {[br] + constructor()[br] + {[br] + $$->%sintbl[]= $array( 0, 38, 71, 92, 100, 92, 71, 38,0, -38, -71, -92, -100, -92, -71, -38);[br] + $$->%index=0[br] + $$->$starttimer( 30 );[br] + $$->$resize(800,600 );[br] + $$->%string=$0[br] + $$->%waitfor=1;[br] + $$->%nextanim=0[br] + [br] + #zoom and rotation anim[br] + $$->%Zoomindex=11[br] + $$->%degree=0[br] + $$->%Noanim=0[br] + $$->%scrollright=-450[br] + [br] + #anim effect init[br] + $$->%xoffset=4[br] + $$->%yoffset=3[br] + $$->%xstart=270[br] + $$->%ystart=200[br] + $$->%b=0[br] + $$->%yoffs=400[br] + [br] + #parallax parameter[br] + $$->%Off=400[br] + $$->%roll=1[br] + }[br] + timerevent()[br] + {[br] + $$->%b = $(($$->%b + 1) & 15);[br] + if ($$->%nextanim == 1) $$->$repaint(1);[br] + $$->$repaint(0);[br] + }[br] + drawAnim()[br] + {[br] + %P->$setFont(32,"times",bold);[br] + %w=$(%P->$fontMetricsWidth($$->%string[$$->%index]) + 20);[br] + %h=$(%P->$fontMetricsHeight * 2);[br] + %pmx = $(($$->$width/2) -%w/2);[br] + %pmy = $(($$->$height()/2) - %h/2);[br] + %x = 10;[br] + %y= $((%h/2) + $$->$fontDescent());[br] + %i=0[br] + while ( $str.mid("Grifisx/Noldor",%i,1) != "") [br] + {[br] + %i16 = $(($$->%b+%i) & 15);[br] + %char=$str.mid("Grifisx/Noldor",%i,1)[br] + %P->$setPen($((15-%i16)*16),$((15-%i16)*16),$((15-%i16)*16) );[br] + %P->$drawText( $(%x+$$->%xstart),$($$->%ystart+%y-$$->%sintbl[%i16]*%h/800),%char,1,Auto);[br] + %x += %P->$fontMetricsWidth(%char);[br] + %i++;[br] + }[br] + }[br] + matrixeffect()[br] + {[br] + if (($$->%Zoomindex == 99) && ($$->%degree==360)) return %P->$drawPixmap($(400-32),$(300-32),"kvirc.png",0,0,-1,-1)[br] + %P->$scale(0.$$->%Zoomindex,0.$$->%Zoomindex)[br] + if ($$->%Zoomindex != 99) $$->%Zoomindex++;[br] + %P->$rotate($$->%degree)[br] + %P->$translate(400,300)[br] + %P->$drawPixmap(-32,-32,"kvirc.png",0,0,-1,-1)[br] + %P->$setFont(28,"times",bold);[br] + %P->$reset()[br] + if ($$->%scrollright >= 550) return[br] + %P->$scale(0.$$->%Zoomindex,0.$$->%Zoomindex)[br] + %P->$translate(400,350)[br] + %P->$drawText($$->%scrollright,10,"Another cool class brought to you by...",-1,Auto) [br] + $$->%scrollright += 3;[br] + %P->$reset()[br] + }[br] + nextanim()[br] + {[br] + %p=$new(painter)[br] + %p->$setBackgroundMode(Opaque)[br] + %p->$setBrush($rand(255),$rand(255),$rand(255))[br] + %p->$begin($$)[br] + %rand=$rand(5)[br] + %p->$drawrect($rand(800),$rand(400),120,200)[br] + %p->$drawArc($rand(800),$rand(400),120,200,20,$(16*20))[br] + %p->$drawPie($rand(800),$rand(400),120,200,20,$(16*20))[br] + %p->$drawChord($rand(800),$rand(400),120,200,20,$(16*20))[br] + %p->$drawEllipse($rand(800),$rand(400),100,30)[br] + %p->$end()[br] + delete %p[br] + }[br] + paintEvent()[br] + {[br] + if ($$->%nextanim ==1) return $$->$nextanim()[br] + # pixmap creation: every effect will be painted on it then copied on widget[br] + %pixmap=$new(pixmap)[br] + %pixmap->$resize($$->$width(),$$->$height())[br] + [br] + # painter creation [br] + %P=$new(painter);[br] + %P->$begin(%pixmap);[br] + $$->$drawanim[br] + $$->$matrixeffect[br] + %i=0[br] + while (%i != 100)[br] + {[br] + %i16 = $(($$->%b+%i) & 15);[br] + %P->$setPen($((15-%i16)*16),$((15-%i16)*16),$((15-%i16)*16) );[br] + %P->$drawpoint($rand(800),$rand(600))[br] + %i++[br] + }[br] + [br] + # sets the animations order to manage the parallax effect[br] + %P->$end[br] + objects.bitBlt $$ 0 0 %pixmap[br] + delete %pixmap[br] + delete %P[br] + if (%Pauseflag == 1) return[br] + [br] + # manage the animations parameters[br] + if (($$->%Off<=60) && ($$->%roll<182)) $$->%roll += 2;[br] + if ($$->%roll>182) $$->%waitfor=0[br] + if ($$->%Noanim != 1) $$->%degree += 16;[br] + if ($$->%degree >= 360)[br] + {[br] + $$->%degree=0;[br] + if ($$->%Zoomindex == 99) $$->%Noanim=1[br] + } [br] + if ($$->%Noanim != 1) return[br] + [br] + #sinusoid animation[br] + if (($$->%xstart <1) && ($$->%xoffset == -4)) $$->%xoffset=4;[br] + if (($$->%xstart >$($$->$width()-%P->$fontMetricsWidth("Grifisx/Noldor"))) && ($$->%xoffset == 4)) $$->%xoffset=-4;[br] + if (($$->%ystart <1) && ($$->%yoffset == -3)) $$->%yoffset=3;[br] + if (($$->%ystart >$($$->$height()-60)) && ($$->%yoffset == 3)) $$->%yoffset=-3;[br] + $$->%xstart += $$->%xoffset;[br] + $$->%ystart += $$->%yoffset;[br] + }[br] + }[br] + [br] + %Hello=$new(hello)[br] + %Hello->$setWindowTitle("Painter effects" );[br] + %Hello->$setFont(28,"times",bold);[br] + %Btn=$new(button,%Hello)[br] + %Btn->$setmaximumwidth(80)[br] + %Btn->$setmaximumheight(30)[br] + %Btn->$setFont(8,"times",bold);[br] + %Btn->$settext(Next)[br] + [br] + privateimpl(%Btn,mousepressevent)[br] + {[br] + if ($$->$parent->%nextanim==0) [br] + {[br] + $$->$parent->%nextanim=1[br] + $$->$settext(Prev)[br] + } [br] + else[br] + {[br] + $$->$parent->%nextanim=0[br] + $$->$settext(Next)[br] + }[br] + }[br] + [br] + %lay=$new(layout,%Hello)[br] + %lay->$addwidget(%Btn,4,0)[br] + %Hello->$setBackgroundColor("000000");[br] + %Hello->$setmaximumwidth(800)[br] + %Hello->$setminimumwidth(780)[br] + %Hello->$setmaximumheight(600)[br] + %Hello->$setminimumheight(600)[br] + %Hello->$move(10,10)[br] + %Hello->$show();[br] [br] + +*/ + +// ======================================================================== +KVSO_BEGIN_REGISTERCLASS(KvsObject_painter,"painter","object") + + // Fonts + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,setFont) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,setFontSize) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,fontAscent) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,fontDescent) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,fontMetricsHeight) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,fontMetricsWidth) + + // Draws + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,drawRect) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,drawLine) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,drawRoundRect) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,drawPoint) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,drawArc) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,drawEllipse) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,drawPie) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,drawChord) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,fillRect) + + // Text & Pixmap & Icons + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,drawText) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,drawPixmap) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,drawIcon) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,drawHtmlText) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,htmlTextSize) + + + // Transform Operation + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,rotate) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,shear) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,scale) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,translate) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,reset) + + + + // ?? + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,setOpacity) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,setTextAntialiasing) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,setAntialiasing) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,setSmoothPixmapTransform) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,setBackGroundMode) + + + + // QPainterPath stuff + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,drawPath) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,resetPath) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,pathAddText) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,pathMoveTo) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,pathLineTo) + + // Pen + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,setPenJoinStyle) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,setPenCapStyle) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,setPenWidth) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,setPenStyle) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,setPen) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,colorNames) + + + // Brush + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,setBrush) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,setBrushStyle) + + + // Gradients + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,setGradientStart) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,setGradientStop) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,setGradientColor) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,setGradientAsBrush) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,clearGradient) + + // painter state + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,save) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,restore) + + // painter device + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,painterDeviceWidth) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,painterDeviceHeight) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,begin) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,end) + + // extra + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_painter,beginPdf) + + +KVSO_END_REGISTERCLASS(KvsObject_painter) + + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_painter,KviKvsObject) + + m_pPainter = new QPainter(); + bDonotdeleteinternalqpainter=false; + m_pPrinter = 0 ; + m_pDeviceObject=0; + m_pPainterPath=0; + m_pGradient=0; + +KVSO_END_CONSTRUCTOR(KvsObject_painter) + +KVSO_BEGIN_DESTRUCTOR(KvsObject_painter) + +if (m_pPainterPath) delete m_pPainterPath; + m_pPainterPath=0; +if (m_pGradient) delete m_pGradient; + m_pGradient=0; +if (m_pPainter && !bDonotdeleteinternalqpainter) delete m_pPainter; + m_pPainter = 0; +if (m_pPrinter) delete m_pPrinter; + m_pPrinter = 0; + +KVSO_END_CONSTRUCTOR(KvsObject_painter) + +#define KVSO_PARAMETERS_PAINTER(__pXOrArray,__iY,__iW,__iH)\ +if(__pXOrArray->isArray())\ + {\ + if(__pXOrArray->array()->size() < 4)\ + {\ + c->error(__tr2qs_ctx("The array passed as parameter must contain at least 4 elements","objects"));\ + return false;\ + }\ + KviKvsVariant * pX = __pXOrArray->array()->at(0);\ + KviKvsVariant * pY = __pXOrArray->array()->at(1);\ + KviKvsVariant * pW = __pXOrArray->array()->at(2);\ + KviKvsVariant * pH = __pXOrArray->array()->at(3);\ + if(!(pX && pY && pW && pH))\ + {\ + c->error(__tr2qs_ctx("One of the geometry array parameters is empty","objects"));\ + return false;\ + }\ + if(!(pX->asInteger(iX) && pY->asInteger(__iY) && pW->asInteger(__iW) && pH->asInteger(__iH)))\ + {\ + c->error(__tr2qs_ctx("One of the geometry array parameters didn't evaluate to an integer","objects"));\ + return false;\ + }\ + } else {\ + if(c->params()->count() < 4)\ + {\ + QString error=function+__tr2qs_ctx(" requires either an array as first parameter or four integers","objects");\ + c->error(error);\ + return false;\ + }\ + if(!__pXOrArray->asInteger(iX))\ + {\ + c->error(__tr2qs_ctx("The first parameter didn't evaluate to an array nor an integer","objects"));\ + return false;\ + }\ + }\ + +#define KVSO_2ARRAYPARAMETERS(__pXOrArray,__iY)\ +if(__pXOrArray->isArray())\ + {\ + if(__pXOrArray->array()->size() < 2)\ + {\ + c->error(__tr2qs_ctx("The array passed as parameter must contain at least 2 elements","objects"));\ + return false;\ + }\ + KviKvsVariant * pX = __pXOrArray->array()->at(0);\ + KviKvsVariant * pY = __pXOrArray->array()->at(1);\ + if(!(pX && pY ))\ + {\ + c->error(__tr2qs_ctx("One of the array parameters is empty","objects"));\ + return false;\ + }\ + if(!(pX->asInteger(iX) && pY->asInteger(__iY)))\ + {\ + c->error(__tr2qs_ctx("One of the array parameters didn't evaluate to an integer","objects"));\ + return false;\ + }\ + } else {\ + if(c->params()->count() < 2)\ + {\ + QString error=function+__tr2qs_ctx(" requires either an array as first parameter or two integers","objects");\ + c->error(error);\ + return false;\ + }\ + if(!__pXOrArray->asInteger(iX))\ + {\ + c->error(__tr2qs_ctx("The first parameter didn't evaluate to an array nor an integer","objects"));\ + return false;\ + }\ + }\ + +#define KVSO_3OR4ARRAYPARAMETERS(__pCol1OrArray,__iCol2,__iCol3,__iOpacity)\ +if(__pCol1OrArray->isArray())\ + {\ + if(__pCol1OrArray->array()->size() < 3)\ + {\ + c->error(__tr2qs_ctx("The array passed as parameter must contain at least 3 elements","objects"));\ + return false;\ + }\ + KviKvsVariant * c1 = __pCol1OrArray->array()->at(0);\ + KviKvsVariant * c2 = __pCol1OrArray->array()->at(1);\ + KviKvsVariant * c3 = __pCol1OrArray->array()->at(2);\ + if(!(c1 && c2 && c3))\ + {\ + c->error(__tr2qs_ctx("One of the array parameters is empty","objects"));\ + return false;\ + }\ + if(!(c1->asInteger(iCol1) && c2->asInteger(__iCol2) && c3->asInteger(__iCol3)))\ + {\ + c->error(__tr2qs_ctx("One of the array parameters didn't evaluate to an integer","objects"));\ + return false;\ + }\ + if(__pCol1OrArray->array()->size() > 3)\ + {\ + KviKvsVariant * c4 = __pCol1OrArray->array()->at(3);\ + if(!(c4->asInteger(__iOpacity)))\ + {\ + c->error(__tr2qs_ctx("The opacity value didn't evaluate to an integer","objects"));\ + return false;\ + }\ + }\ + } else {\ + if(c->params()->count() < 3)\ + {\ + QString error=function+__tr2qs_ctx(" requires either an array as first parameter or 3 integers","objects");\ + c->error(error);\ + return false;\ + }\ + if(!__pCol1OrArray->asInteger(iCol1))\ + {\ + c->error(__tr2qs_ctx("The first parameter didn't evaluate to an array nor an integer","objects"));\ + return false;\ + }\ + }\ + +KVSO_CLASS_FUNCTION(painter,setFont) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + QString szFamily; + QStringList szListStyle; + kvs_int_t iSize; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("size",KVS_PT_INTEGER,0,iSize) + KVSO_PARAMETER("family",KVS_PT_STRING,0,szFamily) + KVSO_PARAMETER("style",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,szListStyle) + KVSO_PARAMETERS_END(c) + QFont font=m_pPainter->font(); + font.setFamily(szFamily); + font.setPointSize(iSize); + QString szStyle; + for(int i=0;iwarning(__tr2qs_ctx("Unknown style '%Q'","objects"),&szStyle); + } + m_pPainter->setFont(font); + return true; +} + +KVSO_CLASS_FUNCTION(painter,setFontSize) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_uint_t uSize; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("size",KVS_PT_UNSIGNEDINTEGER,0,uSize) + KVSO_PARAMETERS_END(c) + QFont font=m_pPainter->font(); + font.setPointSize(uSize); + m_pPainter->setFont(font); + return true; +} + +KVSO_CLASS_FUNCTION(painter,setBackGroundMode) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + QString szMode; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("background mode",KVS_PT_STRING,0,szMode) + KVSO_PARAMETERS_END(c) + if(KviQString::equalCI(szMode,"Transparent")) m_pPainter->setBackgroundMode(Qt::TransparentMode); + else if(KviQString::equalCI(szMode,"Opaque")) m_pPainter->setBackgroundMode(Qt::OpaqueMode); + else c->warning( __tr2qs_ctx("Unknown '%Q' background mode","objects"),&szMode); + return true; +} + +KVSO_CLASS_FUNCTION(painter,drawLine) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + KviKvsVariant * pXOrArray; + kvs_int_t iX,iY,iX1,iY1; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("x_or_array",KVS_PT_VARIANT,0,pXOrArray) + KVSO_PARAMETER("y",KVS_PT_INT,KVS_PF_OPTIONAL,iY) + KVSO_PARAMETER("x1",KVS_PT_INT,KVS_PF_OPTIONAL,iX1) + KVSO_PARAMETER("y1",KVS_PT_INT,KVS_PF_OPTIONAL,iY1) + KVSO_PARAMETERS_END(c) + QString function="$drawLine"; + KVSO_PARAMETERS_PAINTER(pXOrArray,iY,iX1,iY1) + if(m_pPainter) m_pPainter->drawLine(iX,iY,iX1,iY1); + return true; +} + +KVSO_CLASS_FUNCTION(painter,drawRect) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + KviKvsVariant * pXOrArray; + kvs_int_t iX,iY,iW,iH; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("x_or_array",KVS_PT_VARIANT,0,pXOrArray) + KVSO_PARAMETER("y",KVS_PT_INT,KVS_PF_OPTIONAL,iY) + KVSO_PARAMETER("w",KVS_PT_INT,KVS_PF_OPTIONAL,iW) + KVSO_PARAMETER("h",KVS_PT_INT,KVS_PF_OPTIONAL,iH) + KVSO_PARAMETERS_END(c) + QString function="$drawRect"; + KVSO_PARAMETERS_PAINTER(pXOrArray,iY,iW,iH) + m_pPainter->drawRect(iX,iY,iW,iH); + return true; +} + + +KVSO_CLASS_FUNCTION(painter,drawEllipse) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + KviKvsVariant * pXOrArray; + kvs_int_t iX,iY,iW,iH; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("x_or_array",KVS_PT_VARIANT,0,pXOrArray) + KVSO_PARAMETER("y",KVS_PT_INT,KVS_PF_OPTIONAL,iY) + KVSO_PARAMETER("w",KVS_PT_INT,KVS_PF_OPTIONAL,iW) + KVSO_PARAMETER("h",KVS_PT_INT,KVS_PF_OPTIONAL,iH) + KVSO_PARAMETERS_END(c) + QString function="$drawEllipse"; + KVSO_PARAMETERS_PAINTER(pXOrArray,iY,iW,iH) + m_pPainter->drawEllipse(iX,iY,iW,iH); + return true; +} + +KVSO_CLASS_FUNCTION(painter,drawRoundRect) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + KviKvsVariant * pXOrArray; + kvs_int_t iXrnd,iYrnd,iX,iY,iW,iH; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("x_round",KVS_PT_INT,0,iXrnd) + KVSO_PARAMETER("y_round",KVS_PT_INT,0,iYrnd) + KVSO_PARAMETER("x_or_array",KVS_PT_VARIANT,0,pXOrArray) + KVSO_PARAMETER("y",KVS_PT_INT,KVS_PF_OPTIONAL,iY) + KVSO_PARAMETER("w",KVS_PT_INT,KVS_PF_OPTIONAL,iW) + KVSO_PARAMETER("h",KVS_PT_INT,KVS_PF_OPTIONAL,iH) + KVSO_PARAMETERS_END(c) + QString function="$drawRoundRect"; + KVSO_PARAMETERS_PAINTER(pXOrArray,iY,iW,iH) + m_pPainter->drawRoundRect(iX,iY,iW,iH,iXrnd,iYrnd); + return true; +} + +KVSO_CLASS_FUNCTION(painter,drawArc) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + KviKvsVariant * pXOrArray; + kvs_int_t iSangle,iLena,iX,iY,iW,iH; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("start_angle",KVS_PT_INT,0,iSangle) + KVSO_PARAMETER("a_lenght",KVS_PT_INT,0,iLena) + KVSO_PARAMETER("x_or_array",KVS_PT_VARIANT,0,pXOrArray) + KVSO_PARAMETER("y",KVS_PT_INT,KVS_PF_OPTIONAL,iY) + KVSO_PARAMETER("w",KVS_PT_INT,KVS_PF_OPTIONAL,iW) + KVSO_PARAMETER("h",KVS_PT_INT,KVS_PF_OPTIONAL,iH) + KVSO_PARAMETERS_END(c) + QString function="$drawArc"; + KVSO_PARAMETERS_PAINTER(pXOrArray,iY,iW,iH) + m_pPainter->drawArc(iX,iY,iW,iH,iSangle,iLena); + return true; +} + +KVSO_CLASS_FUNCTION(painter,drawChord) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + KviKvsVariant * pXOrArray; + kvs_int_t iSangle,iLena,iX,iY,iW,iH; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("start_angle",KVS_PT_INT,0,iSangle) + KVSO_PARAMETER("a_lenght",KVS_PT_INT,0,iLena) + KVSO_PARAMETER("x_or_array",KVS_PT_VARIANT,0,pXOrArray) + KVSO_PARAMETER("y",KVS_PT_INT,KVS_PF_OPTIONAL,iY) + KVSO_PARAMETER("w",KVS_PT_INT,KVS_PF_OPTIONAL,iW) + KVSO_PARAMETER("h",KVS_PT_INT,KVS_PF_OPTIONAL,iH) + KVSO_PARAMETERS_END(c) + QString function="$drawChord"; + KVSO_PARAMETERS_PAINTER(pXOrArray,iY,iW,iH) + m_pPainter->drawChord(iX,iY,iW,iH,iSangle,iLena); + return true; +} + +KVSO_CLASS_FUNCTION(painter,setBrush) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_int_t iCol1,iCol2,iCol3,iOpacity; + KviKvsVariant *var1,*var2,*var3; + QString szColorMode,szColor; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("Color_1_Or_Colorname_Or_Pixmap",KVS_PT_VARIANT,0,var1) + KVSO_PARAMETER("Color_2",KVS_PT_VARIANT,KVS_PF_OPTIONAL,var2) + KVSO_PARAMETER("Colo3_3",KVS_PT_VARIANT,KVS_PF_OPTIONAL,var3) + KVSO_PARAMETER("color_mode",KVS_PT_STRING,KVS_PF_OPTIONAL,szColorMode) + KVSO_PARAMETER("opacity",KVS_PT_INT,KVS_PF_OPTIONAL,iOpacity) + KVSO_PARAMETERS_END(c) + if(var1->isHObject()) + { + kvs_hobject_t hObj; + var1->asHObject(hObj); + KviKvsObject *pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObj); + if (!pObject) + { + c->warning(__tr2qs_ctx("Pixmap parameter is not an object!","objects")); + return true; + } + if(pObject->inheritsClass("pixmap")) + m_pPainter->setBrush(*((KvsObject_pixmap *)pObject)->getPixmap()); + else c->warning(__tr2qs_ctx("Object Pixmap required!","objects")); + return true; + } + if (!var1->asInteger(iCol1)) + { + var1->asString(szColor); + if (c->paramCount()<2) iOpacity=255; + else + { + if (!var2->asInteger(iOpacity)) + { + c->warning(__tr2qs_ctx("The opacity parameter didn't evaluate to integer","objects")); + return true; + } + } + QColor col(szColor); + col.setAlpha(iOpacity); + m_pPainter->setBrush(col); + } + else + { + if(c->paramCount()<3) + { + c->error(__tr2qs_ctx("Color name or triplette rgb/hsv value required","objects")); + return true; + } + if (!var2->asInteger(iCol2)||!var3->asInteger(iCol3)) + { + c->error(__tr2qs_ctx("One of the triplette parameters didn't evaluate to an integer","objects"));\ + return true; + } + if (c->paramCount()<5) iOpacity=255; + QColor col; + if(KviQString::equalCI(szColorMode, "HSV")) + col.setHsv(iCol1,iCol2,iCol3,iOpacity); + else + col.setRgb(iCol1,iCol2,iCol3,iOpacity); + m_pPainter->setBrush(col); + + } + return true; +} + +KVSO_CLASS_FUNCTION(painter,setPen) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_int_t iCol1,iCol2,iCol3,iOpacity; + QString szColorMode,szColor; + KviKvsVariant *var1,*var2,*var3; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("Color_1_Or_Colorname",KVS_PT_VARIANT,0,var1) + KVSO_PARAMETER("Color_2",KVS_PT_VARIANT,KVS_PF_OPTIONAL,var2) + KVSO_PARAMETER("Colo3_3",KVS_PT_VARIANT,KVS_PF_OPTIONAL,var3) + KVSO_PARAMETER("color_mode",KVS_PT_STRING,KVS_PF_OPTIONAL,szColorMode) + KVSO_PARAMETER("opacity",KVS_PT_INT,KVS_PF_OPTIONAL,iOpacity) + KVSO_PARAMETERS_END(c) + if (!var1->asInteger(iCol1)) + { + var1->asString(szColor); + if (c->paramCount()<2) iOpacity=255; + else + { + if (!var2->asInteger(iOpacity)) + { + c->warning(__tr2qs_ctx("The opacity parameter didn't evaluate to integer","objects")); + return true; + } + } + QColor col(szColor); + col.setAlpha(iOpacity); + m_pPainter->setPen(col); + } + else + { + if(c->paramCount()<3) + { + c->error(__tr2qs_ctx("Color name or triplette rgb/hsv value required","objects")); + return true; + } + if (!var2->asInteger(iCol2)||!var3->asInteger(iCol3)) + { + c->error(__tr2qs_ctx("One of the triplette parameters didn't evaluate to an integer","objects"));\ + return true; + } + if (c->paramCount()<5) iOpacity=255; + QColor col; + if(KviQString::equalCI(szColorMode, "HSV")) + col.setHsv(iCol1,iCol2,iCol3,iOpacity); + else + col.setRgb(iCol1,iCol2,iCol3,iOpacity); + m_pPainter->setPen(col); + + } + + return true; +} + +KVSO_CLASS_FUNCTION(painter,drawPie) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + KviKvsVariant * pXOrArray; + kvs_int_t iSangle,iLena,iX,iY,iW,iH; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("start_angle",KVS_PT_INT,0,iSangle) + KVSO_PARAMETER("a_lenght",KVS_PT_INT,0,iLena) + KVSO_PARAMETER("x_or_array",KVS_PT_VARIANT,0,pXOrArray) + KVSO_PARAMETER("y",KVS_PT_INT,KVS_PF_OPTIONAL,iY) + KVSO_PARAMETER("w",KVS_PT_INT,KVS_PF_OPTIONAL,iW) + KVSO_PARAMETER("h",KVS_PT_INT,KVS_PF_OPTIONAL,iH) + KVSO_PARAMETERS_END(c) + QString function="$drawPie"; + KVSO_PARAMETERS_PAINTER(pXOrArray,iY,iW,iH) + m_pPainter->drawPie(iX,iY,iW,iH,iSangle,iLena); + return true; +} + +KVSO_CLASS_FUNCTION(painter,drawPoint) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + KviKvsVariant * pXOrArray; + kvs_int_t iX,iY; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("x_or_array",KVS_PT_VARIANT,0,pXOrArray) + KVSO_PARAMETER("y",KVS_PT_INT,KVS_PF_OPTIONAL,iY) + KVSO_PARAMETERS_END(c) + QString function="$drawPoint"; + KVSO_2ARRAYPARAMETERS(pXOrArray,iY) + m_pPainter->drawPoint(iX,iY); + return true; +} + +KVSO_CLASS_FUNCTION(painter,fontDescent) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + c->returnValue()->setInteger(m_pPainter->fontMetrics().descent()); + return true; +} + +KVSO_CLASS_FUNCTION(painter,fontAscent) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + c->returnValue()->setInteger(m_pPainter->fontMetrics().ascent()); + return true; + +} + +KVSO_CLASS_FUNCTION(painter,fontMetricsWidth) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETERS_END(c) + if (m_pPainter->isActive()) + c->returnValue()->setInteger(m_pPainter->fontMetrics().width(szText)); + else + c->warning(__tr2qs_ctx("$fontMetricsWidth: the painter is not active!","objects")); + return true; +} + +KVSO_CLASS_FUNCTION(painter,fontMetricsHeight) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + if (m_pPainter->isActive()) + c->returnValue()->setInteger(m_pPainter->fontMetrics().height()); + else + c->warning(__tr2qs_ctx("$fontMetricsHeight: the painter is not active!","objects")); + return true; +} + +KVSO_CLASS_FUNCTION(painter,begin) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + KviKvsObject * pObject; + kvs_hobject_t hObject; + KviKvsVariant *v; + QString szFileName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("paint_device",KVS_PT_VARIANT,0,v) + KVSO_PARAMETER("file_name",KVS_PT_STRING,KVS_PF_OPTIONAL,szFileName) + KVSO_PARAMETERS_END(c) + QPaintDevice * pd; + if(v->isString()) + { + QString szDev; + v->asString(szDev); + if(KviQString::equalCI(szDev,"printer") || KviQString::equalCI(szDev,"pdf")) + { + if (m_pPrinter) delete m_pPrinter; + m_pPrinter=new QPrinter(); + if ( KviQString::equalCI(szDev,"pdf")) + { + // m_pPrinter=new QPrinter(); + if(szFileName.isEmpty()) + { + c->warning(__tr2qs_ctx("Missing filename","objects")); + return true; + } + m_pPrinter->setOutputFormat(QPrinter::PdfFormat); + m_pPrinter->setOutputFileName(szFileName); + } + else + { + QPrintDialog printDialog(m_pPrinter, 0); + if (printDialog.exec() == QDialog::Accepted) + { + qDebug("papersize %d",m_pPrinter->paperSize()); + m_pPainter->begin(m_pPrinter); + return true; + } + else + { + m_pPrinter=0; + return true; + } + } + //if (i==3) m_pPrinter->setPaperSize(QPrinter::A3); + //if (i==4) m_pPrinter->setPaperSize(QPrinter::A4); + } + else + { + c->warning(__tr2qs_ctx("No valid paint device","objects")); + return true; + } + m_pPainter->begin(m_pPrinter); + return true; + } + else if (v->isHObject()) + { + v->asHObject(hObject); + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + if (!pObject) + { + c->warning(__tr2qs_ctx("Pixmap or Widget parameter is not an object","objects")); + return true; + } + if(pObject->inheritsClass("pixmap"))pd=((KvsObject_pixmap *)pObject)->getPixmap(); + else if (pObject->inheritsClass("widget")) pd=((KvsObject_widget *)pObject)->widget(); + else + { + c->warning(__tr2qs_ctx("Widget or Pixmap required ","objects")); + return true; + } + } + else + { + c->warning(__tr2qs_ctx("No valid paint device","objects")); + return true; + } + attachDevice(pObject,pd); + //if (pObject->inheritsClass("pixmap")) ((KvsObject_pixmap *)pObject)->pixmapChanged(); + return true; +} + +void KvsObject_painter::attachDevice(KviKvsObject * o,QPaintDevice * p) +{ + if(m_pDeviceObject)detachDevice(); + m_pDeviceObject = o; + // KvsObject_pixmap and KvsObject_widget object have this signal + // it is emitted BEFORE the real QPaintDevice is deleted, so we can eventually + // call m_pPainter->end() in time + + QObject::connect(m_pDeviceObject,SIGNAL(aboutToDie()),this,SLOT(detachDevice())); + m_pPainter->begin(p); +} + +void KvsObject_painter::detachDevice() +{ + if(!m_pDeviceObject)return; + disconnect(m_pDeviceObject,SIGNAL(aboutToDie()),this,SLOT(detachDevice())); + m_pPainter->end(); + if (m_pPrinter) + { + delete m_pPrinter; + m_pPrinter=0; + } + m_pDeviceObject = 0; +} + +KVSO_CLASS_FUNCTION(painter,end) +{ + Q_UNUSED(c); + + if(!m_pDeviceObject) + { + m_pPainter->end(); + if (m_pPrinter) + { + delete m_pPrinter; + m_pPrinter=0; + } + } + else detachDevice(); + return true; +} + +KVSO_CLASS_FUNCTION(painter,beginPdf) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + QString szFileName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("file_name",KVS_PT_STRING,0,szFileName) + KVSO_PARAMETERS_END(c) + if (m_pPrinter) delete m_pPrinter; + m_pPrinter=new QPrinter();//QPrinter::HighResolution); + m_pPrinter->setOutputFormat(QPrinter::PdfFormat); + m_pPrinter->setOutputFileName(szFileName); + m_pPainter->begin(m_pPrinter); + return true; +} +KVSO_CLASS_FUNCTION(painter,drawText) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + QString szText,szMode; + kvs_int_t iX,iY,iN=-1; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("x",KVS_PT_INT,0,iX) + KVSO_PARAMETER("y",KVS_PT_INT,0,iY) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETER("num_chars",KVS_PT_INT,KVS_PF_OPTIONAL,iN) + KVSO_PARAMETER("mode",KVS_PT_STRING,KVS_PF_OPTIONAL,szMode) + KVSO_PARAMETERS_END(c) + if (!szMode.isEmpty() && !KviQString::equalCI(szMode,"Auto")) + { + if(KviQString::equalCI(szMode,"RTL"))m_pPainter->setLayoutDirection(Qt::RightToLeft); + else if(KviQString::equalCI(szMode,"LTR"))m_pPainter->setLayoutDirection(Qt::LeftToRight); + else + { + c->warning(__tr2qs_ctx("Invalid mode '%Q'","objects"),&szMode); + return true; + } + } + m_pPainter->drawText(iX,iY,szText.left(iN)); + return true; +} + +KVSO_CLASS_FUNCTION(painter,drawPixmap) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_real_t iX,iY; + kvs_int_t iStartx,iStarty,iEndx,iEndy; + bool bTiled; + KviKvsObject *obj; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("x",KVS_PT_REAL,0,iX) + KVSO_PARAMETER("y",KVS_PT_REAL,0,iY) + KVSO_PARAMETER("pixmap",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETER("start_x",KVS_PT_INT,0,iStartx) + KVSO_PARAMETER("start_y",KVS_PT_INT,0,iStarty) + KVSO_PARAMETER("end_x",KVS_PT_INT,0,iEndx) + KVSO_PARAMETER("end_y",KVS_PT_INT,0,iEndy) + KVSO_PARAMETER("b_Tiled",KVS_PT_BOOLEAN,KVS_PF_OPTIONAL,bTiled) + KVSO_PARAMETERS_END(c) + obj=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + if (!obj) + { + c->warning(__tr2qs_ctx("Pixmap parameter is not an object","objects")); + return true; + } + if (!obj->inheritsClass("pixmap")) + { + c->warning(__tr2qs_ctx("Pixmap object required","objects")); + return true; + } + + m_pPainter->drawPixmap(QPointF(iX,iY),*((KvsObject_pixmap *)obj)->getPixmap(),QRect(iStartx,iStarty,iEndx,iEndy)); + return true; +} + +KVSO_CLASS_FUNCTION(painter,rotate) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_real_t dAngle; + QString szAxis; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("angle",KVS_PT_DOUBLE,0,dAngle) + KVSO_PARAMETER("axis",KVS_PT_STRING,KVS_PF_OPTIONAL,szAxis) + KVSO_PARAMETERS_END(c) + Qt::Axis axis = Qt::ZAxis; + if(!szAxis.isEmpty()) + { + if (KviQString::equalCI(szAxis,"XAxis"))axis=Qt::XAxis; + else if (KviQString::equalCI(szAxis,"YAxis")) axis=Qt::YAxis; + else if (KviQString::equalCI(szAxis,"ZAxis")) axis=Qt::ZAxis; + else c->warning(__tr2qs_ctx("Unknown axis '%Q' switching to default ZAxis","objects"),&szAxis); + } + PAINTER_ROTATE(dAngle,axis) + return true; +} + +KVSO_CLASS_FUNCTION(painter,translate) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_real_t dXtrasl,dYtrasl; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("trasl_x",KVS_PT_DOUBLE,0,dXtrasl) + KVSO_PARAMETER("trasl_y",KVS_PT_DOUBLE,0,dYtrasl) + KVSO_PARAMETERS_END(c) + PAINTER_TRANSLATE(dXtrasl,dYtrasl) + return true; +} + +KVSO_CLASS_FUNCTION(painter,shear) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_real_t dShearh,dShearv; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("shear_h",KVS_PT_DOUBLE,0,dShearh) + KVSO_PARAMETER("shear_v",KVS_PT_DOUBLE,0,dShearv) + KVSO_PARAMETERS_END(c) + PAINTER_SHEAR(dShearh,dShearv); + return true; +} + +KVSO_CLASS_FUNCTION(painter,scale) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_real_t dScalex,dScaley; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("scale_x",KVS_PT_DOUBLE,0,dScalex) + KVSO_PARAMETER("scale_y",KVS_PT_DOUBLE,0,dScaley) + KVSO_PARAMETERS_END(c) + PAINTER_SCALE(dScalex,dScaley); + return true; +} + +KVSO_CLASS_FUNCTION(painter,reset) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + m_pPainter->resetTransform(); + return true; +} + +KVSO_CLASS_FUNCTION(painter,drawHtmlText) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + QString szText; + kvs_int_t iX,iY,iW,iH; + + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("x",KVS_PT_INT,0,iX) + KVSO_PARAMETER("y",KVS_PT_INT,0,iY) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETER("w",KVS_PT_INT,0,iW) + KVSO_PARAMETER("h",KVS_PT_INT,0,iH) + + KVSO_PARAMETERS_END(c) + QTextDocument doc; + doc.setHtml(szText); + doc.setDefaultFont(m_pPainter->font()); + m_pPainter->save(); + m_pPainter->translate(iX,iY); + doc.setPageSize(QSize(iW,iH)); + doc.drawContents(m_pPainter); + m_pPainter->restore(); + return true; +} + +KVSO_CLASS_FUNCTION(painter,htmlTextSize) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETERS_END(c) + QTextDocument doc; + doc.setHtml(szText); + doc.setDefaultFont(m_pPainter->font()); + QSizeF size=doc.size(); + KviKvsArray * a = new KviKvsArray(); + a->set(0,new KviKvsVariant((kvs_real_t)size.width())); + a->set(1,new KviKvsVariant((kvs_real_t)size.height())); + c->returnValue()->setArray(a); + return true; +} + +KVSO_CLASS_FUNCTION(painter,drawIcon) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + QString szIcon,szState; + kvs_int_t iX,iY,iW,iH; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("x",KVS_PT_INT,0,iX) + KVSO_PARAMETER("y",KVS_PT_INT,0,iY) + KVSO_PARAMETER("icon",KVS_PT_STRING,0,szIcon) + KVSO_PARAMETER("state",KVS_PT_STRING,KVS_PF_OPTIONAL,szState) + KVSO_PARAMETER("w",KVS_PT_INT,KVS_PF_OPTIONAL,iW) + KVSO_PARAMETER("h",KVS_PT_INT,KVS_PF_OPTIONAL,iH) + KVSO_PARAMETERS_END(c) + QPixmap *pix=g_pIconManager->getImage(szIcon); + if (!pix) + { + c->warning("The icon '%Q' does not exists",&szIcon); + return true; + } + QSize pixsize(pix->width(),pix->height()); + QIcon ico(*pix); + QIcon::Mode mode=QIcon::Normal; + if(!ico.isNull()) + { + if (KviQString::equalCI(szState,"Disabled")) + mode=QIcon::Disabled; + else if (KviQString::equalCI(szState,"Active"))mode=QIcon::Active; + else if (KviQString::equalCI(szState,"Selected"))mode=QIcon::Selected; + if (c->parameterCount()<5) + m_pPainter->drawPixmap(iX,iY,ico.pixmap(pixsize,mode)); + else + m_pPainter->drawPixmap(iX,iY,ico.pixmap(QSize(iW,iH),mode)); + } + return true; +} + +KVSO_CLASS_FUNCTION(painter,setOpacity) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_real_t dOpacity; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("opacity_factor",KVS_PT_DOUBLE,0,dOpacity) + KVSO_PARAMETERS_END(c) + m_pPainter->setOpacity(dOpacity); + return true; +} + +KVSO_CLASS_FUNCTION(painter,setTextAntialiasing) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + m_pPainter->setRenderHint(QPainter::TextAntialiasing,bEnabled); + return true; +} + +KVSO_CLASS_FUNCTION(painter,setAntialiasing) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + m_pPainter->setRenderHint(QPainter::Antialiasing,bEnabled); + return true; +} + +KVSO_CLASS_FUNCTION(painter,setSmoothPixmapTransform) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + m_pPainter->setRenderHint(QPainter::SmoothPixmapTransform,bEnabled); + return true; +} + +KVSO_CLASS_FUNCTION(painter,setPenJoinStyle) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + QString szStyle; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("style",KVS_PT_STRING,0,szStyle) + KVSO_PARAMETERS_END(c) + Qt::PenJoinStyle style=Qt::BevelJoin; + if(KviQString::equalCI(szStyle,"Milter"))style=Qt::MiterJoin; + else if (KviQString::equalCI(szStyle,"Round"))style=Qt::RoundJoin; + QPen pen=m_pPainter->pen(); + pen.setJoinStyle(style); + m_pPainter->setPen(pen); + return true; +} + +KVSO_CLASS_FUNCTION(painter,setPenCapStyle) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + QString szStyle; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("style",KVS_PT_STRING,0,szStyle) + KVSO_PARAMETERS_END(c) + Qt::PenCapStyle style=Qt::SquareCap; + if(KviQString::equalCI(szStyle,"Flat")) style=Qt::FlatCap; + else if (KviQString::equalCI(szStyle,"Round"))style=Qt::RoundCap; + QPen pen=m_pPainter->pen(); + pen.setCapStyle(style); + m_pPainter->setPen(pen); + return true; +} + +KVSO_CLASS_FUNCTION(painter,save) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + m_pPainter->save(); + return true; +} + +KVSO_CLASS_FUNCTION(painter,restore) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + m_pPainter->restore(); + return true; +} + +KVSO_CLASS_FUNCTION(painter,setPenStyle) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + QString szStyle; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("style",KVS_PT_STRING,0,szStyle) + KVSO_PARAMETERS_END(c) + bool found=false; + unsigned int j = 0; + for(; j < penstyles_num; j++) + { + if(KviQString::equalCI(szStyle,penstyles_tbl[j])) + { + found=true; + break; + } + } + QPen pen=m_pPainter->pen(); + if (found){ + pen.setStyle(penstyles_cod[j]); + m_pPainter->setPen(pen); + } + else c->warning(__tr2qs_ctx("Unknown pen style '%Q'","objects"),&szStyle); + return true; +} + +KVSO_CLASS_FUNCTION(painter,setBrushStyle) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + QString szStyle; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("style",KVS_PT_STRING,0,szStyle) + KVSO_PARAMETERS_END(c) + bool found=false; + unsigned int j = 0; + for(; j < brushstyles_num; j++) + { + if(KviQString::equalCI(szStyle,brushstyles_tbl[j])) + { + found=true; + break; + } + } + QBrush brush=m_pPainter->brush(); + if (found){ + brush.setStyle(brushstyles_cod[j]); + m_pPainter->setBrush(brush); + } + else c->warning(__tr2qs_ctx("Unknown brush style '%Q'","objects"),&szStyle); + return true; +} + +KVSO_CLASS_FUNCTION(painter,setGradientStart) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_real_t dX,dY; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("x_Point",KVS_PT_DOUBLE,0,dX) + KVSO_PARAMETER("y_Point",KVS_PT_DOUBLE,0,dY) + KVSO_PARAMETERS_END(c) + if (!m_pGradient) m_pGradient=new(QLinearGradient); + m_pGradient->setStart(dX,dY); + return true; +} + +KVSO_CLASS_FUNCTION(painter,setGradientStop) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_real_t dX,dY; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("x_Point",KVS_PT_DOUBLE,0,dX) + KVSO_PARAMETER("y_Point",KVS_PT_DOUBLE,0,dY) + KVSO_PARAMETERS_END(c) + if (!m_pGradient) m_pGradient=new(QLinearGradient); + m_pGradient->setFinalStop(dX,dY); + return true; +} + +KVSO_CLASS_FUNCTION(painter,setGradientColor) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_real_t dAt; + kvs_int_t iCol1,iCol2,iCol3,iOpacity; + KviKvsVariant *var1,*var2,*var3; + QString szColorMode,szColor; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("at",KVS_PT_DOUBLE,0,dAt) + KVSO_PARAMETER("Color_1_Or_Colorname",KVS_PT_VARIANT,0,var1) + KVSO_PARAMETER("Color_2",KVS_PT_VARIANT,KVS_PF_OPTIONAL,var2) + KVSO_PARAMETER("Colo3_3",KVS_PT_VARIANT,KVS_PF_OPTIONAL,var3) + KVSO_PARAMETER("color_mode",KVS_PT_STRING,KVS_PF_OPTIONAL,szColorMode) + KVSO_PARAMETER("opacity",KVS_PT_INT,KVS_PF_OPTIONAL,iOpacity) + KVSO_PARAMETERS_END(c) + if (!var1->asInteger(iCol1)) + { + var1->asString(szColor); + if (c->paramCount()<3) iOpacity=255; + else + { + if (!var2->asInteger(iOpacity)) + { + c->warning(__tr2qs_ctx("The opacity parameter didn't evaluate to integer","objects")); + return true; + } + } + if (!m_pGradient) m_pGradient=new(QLinearGradient); + QColor col(szColor); + col.setAlpha(iOpacity); + m_pGradient->setColorAt(dAt,col); + } + else + { + if(c->paramCount()<4) + { + c->error(__tr2qs_ctx("Color name or triplette RGB/HSV values required","objects")); + return true; + } + if ( !var2->asInteger(iCol2)||!var3->asInteger(iCol3)) + { + c->error(__tr2qs_ctx("One of the triplette parameters didn't evaluate to an integer","objects"));\ + return true; + } + if (c->paramCount()<5) iOpacity=255; + QColor col; + if(KviQString::equalCI(szColorMode, "HSV")) + col.setHsv(iCol1,iCol2,iCol3,iOpacity); + else + col.setRgb(iCol1,iCol2,iCol3,iOpacity); + if (!m_pGradient) m_pGradient=new(QLinearGradient); + m_pGradient->setColorAt(dAt,col); + + } + return true; +} + +KVSO_CLASS_FUNCTION(painter,setGradientAsBrush) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + if (!m_pGradient) m_pGradient=new(QLinearGradient); + m_pPainter->setBrush(*m_pGradient); + return true; +} + +KVSO_CLASS_FUNCTION(painter,clearGradient) +{ + Q_UNUSED(c); + if (!m_pGradient) delete m_pGradient; + m_pGradient=0; + return true; +} + +KVSO_CLASS_FUNCTION(painter,setPenWidth) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_real_t iWidth; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("width",KVS_PT_REAL,0,iWidth) + KVSO_PARAMETERS_END(c) + QPen pen=m_pPainter->pen(); + pen.setWidthF(iWidth); + m_pPainter->setPen(pen); + return true; +} + +KVSO_CLASS_FUNCTION(painter,fillRect) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_int_t iX,iY,iW,iH; + kvs_int_t iCol1,iCol2,iCol3,iOpacity; + QString szColorMode; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("x",KVS_PT_INT,0,iX) + KVSO_PARAMETER("y",KVS_PT_INT,0,iY) + KVSO_PARAMETER("w",KVS_PT_INT,0,iW) + KVSO_PARAMETER("h",KVS_PT_INT,0,iH) + KVSO_PARAMETER("Color_1",KVS_PT_INT,0,iCol1) + KVSO_PARAMETER("Color_2",KVS_PT_INT,0,iCol2) + KVSO_PARAMETER("Colo3_3",KVS_PT_INT,0,iCol3) + KVSO_PARAMETER("opacity",KVS_PT_INT,KVS_PF_OPTIONAL,iOpacity) + KVSO_PARAMETER("color_mode",KVS_PT_STRING,KVS_PF_OPTIONAL,szColorMode) + KVSO_PARAMETERS_END(c) + if (c->paramCount()<8) iOpacity=255; + QColor col; + if(KviQString::equalCI(szColorMode, "HSV")) + col.setHsv(iCol1,iCol2,iCol3,iOpacity); + else + col.setRgb(iCol1,iCol2,iCol3,iOpacity); + m_pPainter->fillRect(iX,iY,iW,iH,col); + return true; +} + +KVSO_CLASS_FUNCTION(painter,colorNames) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + QStringList color=QColor::colorNames(); + KviKvsArray * a = new KviKvsArray(); + //a->set(0,new KviKvsVariant((kvs_int_t)col.red())); + for(int i=0;iset(i,new KviKvsVariant(color.at(i))); + } + c->returnValue()->setArray(a); + return true; +} +KVSO_CLASS_FUNCTION(painter,painterDeviceWidth) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_int_t width=m_pPainter->device()->width(); + c->returnValue()->setInteger(width); + return true; +} +KVSO_CLASS_FUNCTION(painter,painterDeviceHeight) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_int_t height=m_pPainter->device()->height(); + c->returnValue()->setInteger(height); + return true; +} +KVSO_CLASS_FUNCTION(painter,pathMoveTo) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_real_t dX,dY; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("x",KVS_PT_REAL,0,dX) + KVSO_PARAMETER("y",KVS_PT_REAL,0,dY) + KVSO_PARAMETERS_END(c) + if (!m_pPainterPath) m_pPainterPath=new QPainterPath(QPointF(0,0)); + m_pPainterPath->moveTo(dX,dY); + return true; +} + +KVSO_CLASS_FUNCTION(painter,pathLineTo) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_real_t dX,dY; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("x",KVS_PT_REAL,0,dX) + KVSO_PARAMETER("y",KVS_PT_REAL,0,dY) + KVSO_PARAMETERS_END(c) + if (!m_pPainterPath) m_pPainterPath=new QPainterPath(QPointF(0,0)); + m_pPainterPath->lineTo(dX,dY); + return true; +} + +KVSO_CLASS_FUNCTION(painter,pathAddText) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + kvs_real_t dX,dY; + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("x",KVS_PT_REAL,0,dX) + KVSO_PARAMETER("y",KVS_PT_REAL,0,dY) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETERS_END(c) + if (!m_pPainterPath) m_pPainterPath=new QPainterPath(QPointF(0,0)); + m_pPainterPath->addText(dX,dY,m_pPainter->font(),szText); + return true; +} + +KVSO_CLASS_FUNCTION(painter,drawPath) +{ + CHECK_INTERNAL_POINTER(m_pPainter) + m_pPainter->drawPath(*m_pPainterPath); + //delete m_pPainterPath; + //m_pPainterPath=0; + return true; +} + +KVSO_CLASS_FUNCTION(painter,resetPath) +{ + Q_UNUSED(c); + if (m_pPainterPath){ + delete m_pPainterPath; + m_pPainterPath=0; + } + return true; +} +void KvsObject_painter::setInternalPainter(QPainter *p) +{ + delete m_pPainter; + m_pPainter=p; + bDonotdeleteinternalqpainter=true; +} +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_painter.moc" +#endif //COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/objects/KvsObject_painter.h b/src/modules/objects/KvsObject_painter.h new file mode 100644 index 000000000..e8529dfb0 --- /dev/null +++ b/src/modules/objects/KvsObject_painter.h @@ -0,0 +1,131 @@ +#ifndef _CLASS_PAINTER_H_ +#define _CLASS_PAINTER_H_ +//============================================================================= +// +// File : KvsObject_painter.h +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include + +#include +#include +#include "KviCString.h" +#include +#include "object_macros.h" + + +class KvsObject_painter : public KviKvsObject +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_painter) +protected: + QPrinter * m_pPrinter; + bool bDonotdeleteinternalqpainter; + QPainter * m_pPainter; + QMatrix m_pMatrix; + QLinearGradient *m_pGradient; + QPainterPath *m_pPainterPath; +public: + void setInternalPainter(QPainter *p); + bool setFont(KviKvsObjectFunctionCall *c); + bool setFontSize(KviKvsObjectFunctionCall *c); + + bool fontAscent(KviKvsObjectFunctionCall *c); + bool fontDescent(KviKvsObjectFunctionCall *c); + bool fontMetricsWidth(KviKvsObjectFunctionCall *c); + bool fontMetricsHeight(KviKvsObjectFunctionCall *c); + bool setBrush(KviKvsObjectFunctionCall *c); + bool setPen(KviKvsObjectFunctionCall *c); + bool setBackGroundMode(KviKvsObjectFunctionCall *c); + + bool drawRect(KviKvsObjectFunctionCall *c); + bool drawWinFocusRect(KviKvsObjectFunctionCall *c); + bool drawLine(KviKvsObjectFunctionCall *c); + bool drawRoundRect(KviKvsObjectFunctionCall *c); + bool drawPoint(KviKvsObjectFunctionCall *c); + bool drawArc(KviKvsObjectFunctionCall *c); + bool drawChord(KviKvsObjectFunctionCall *c); + bool drawPie(KviKvsObjectFunctionCall *c); + bool drawEllipse(KviKvsObjectFunctionCall *c); + + bool drawText(KviKvsObjectFunctionCall *c); + bool drawPixmap(KviKvsObjectFunctionCall *c); + + + bool begin(KviKvsObjectFunctionCall *c); + bool end(KviKvsObjectFunctionCall *c); + bool save(KviKvsObjectFunctionCall *c); + bool restore(KviKvsObjectFunctionCall *c); + + + bool scale(KviKvsObjectFunctionCall *c); + bool shear(KviKvsObjectFunctionCall *c); + bool rotate(KviKvsObjectFunctionCall *c); + bool reset(KviKvsObjectFunctionCall *c); + bool translate(KviKvsObjectFunctionCall *c); + bool setPenStyle(KviKvsObjectFunctionCall *c); + bool setBrushStyle(KviKvsObjectFunctionCall *c); + +// QT4 + bool setOpacity(KviKvsObjectFunctionCall *c); + bool setSmoothPixmapTransform(KviKvsObjectFunctionCall *c); + bool setTextAntialiasing(KviKvsObjectFunctionCall *c); + bool setAntialiasing(KviKvsObjectFunctionCall *c); + bool setGradientStart(KviKvsObjectFunctionCall *c); + bool setGradientStop(KviKvsObjectFunctionCall *c); + bool setGradientColor(KviKvsObjectFunctionCall *c); + bool setGradientAsBrush(KviKvsObjectFunctionCall *c); + bool clearGradient(KviKvsObjectFunctionCall *c); + + bool drawIcon(KviKvsObjectFunctionCall *c); + bool drawHtmlText(KviKvsObjectFunctionCall *c); + bool htmlTextSize(KviKvsObjectFunctionCall *c); + bool fillRect(KviKvsObjectFunctionCall *c); + bool setPenWidth(KviKvsObjectFunctionCall *c); + bool colorNames(KviKvsObjectFunctionCall *c); + bool pathMoveTo(KviKvsObjectFunctionCall *c); + bool pathLineTo(KviKvsObjectFunctionCall *c); + bool drawPath(KviKvsObjectFunctionCall *c); + bool setPenJoinStyle(KviKvsObjectFunctionCall *c); + bool setPenCapStyle(KviKvsObjectFunctionCall *c); + bool pathAddText(KviKvsObjectFunctionCall *c); + bool resetPath(KviKvsObjectFunctionCall *c); + + bool beginPdf(KviKvsObjectFunctionCall *c); + + bool painterDeviceWidth(KviKvsObjectFunctionCall *c); + bool painterDeviceHeight(KviKvsObjectFunctionCall *c); + + +protected: + void attachDevice(KviKvsObject * o,QPaintDevice * p); +protected slots: + void detachDevice(); +private: + KviKvsObject * m_pDeviceObject; +}; +#endif // !_CLASS_PAINTER_H_ + + + diff --git a/src/modules/objects/KvsObject_pixmap.cpp b/src/modules/objects/KvsObject_pixmap.cpp new file mode 100644 index 000000000..64128ef5d --- /dev/null +++ b/src/modules/objects/KvsObject_pixmap.cpp @@ -0,0 +1,360 @@ +//============================================================================= +// +// File : KvsObject_pixmap.cpp +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_pixmap.h" +#include "KvsObject_widget.h" + +#include "KvsObject_memoryBuffer.h" +#include "KviAnimatedPixmap.h" + +#include "kvi_debug.h" +#include "KviLocale.h" + +#include + +/* + @doc: pixmap + @keyterms: + pixmap object class + @title: + pixmap class + @type: + class + @short: + This class provide a pixmap. + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + The pixmap class is an off-screen, pixel-based paint device. + @functions: + !fn: $fill(,,) + Fills the pixmap with the widget's background color or pixmap.[br] + Note that x_offset, y_offest are offsets in the widget. + !fn: $resize(,) + Resizes the pixmap to w width and h height. Set wh or hg to 0, to have a null pixmap. + !fn: $scale(,,[]) + Scales the pixmap or the animation by sx horizontally and sy vertically. + Aspect_ratio values: + - IgnoreAspectRatio:the pixmap is scaled ignoring his aspect ratio. + - KeepAspectRatio: pixmap is scaled to a rectangle as large as possible inside size, preserving the aspect ratio. + - KeepAspectRatioByExpanding, the pixmap is scaled to a rectangle as small as possible outside size, preserving the aspect ratio. + Default value is KeepAspectRatio. + !fn: $load() + Load a pixmap from the file . + !fn: $save() + Save the pixmap or the current animation frame to the file . + !fn: $loadAnimation() + Load an animation from the file and start it. + !fn: $startAnimation() + Start the animation. + !fn: $stopAnimation() + Stop the animation. + !fn: $height() + Return the height of the pixmap or of the animation. + !fn: $width() + Return the width of the pixmap or of the animation. + !fn: $frameChangedEvent() + This event is triggered by KVIrc when the current animation frame changes. + @signals: + !sg: $frameChanged() + This signal is emitted by the default implementation of [classfnc]$frameChangedEvent[/classfnc]().[br] + +*/ + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_pixmap,"pixmap","object") + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,fill) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,resize) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,scale) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,load) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,loadAnimation) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,save) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,startAnimation) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,stopAnimation) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,loadFromMemoryBuffer) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,height) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,width) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,grabWidget) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,frameChangedEvent) + +KVSO_END_REGISTERCLASS(KvsObject_pixmap) + + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_pixmap,KviKvsObject) + m_pAnimatedPixmap = 0; + m_pPixmap = 0; +KVSO_END_CONSTRUCTOR(KvsObject_pixmap) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_pixmap) + emit aboutToDie(); + if (m_pPixmap)delete m_pPixmap; + if (m_pAnimatedPixmap) delete m_pAnimatedPixmap; +KVSO_END_CONSTRUCTOR(KvsObject_pixmap) + + +KVSO_CLASS_FUNCTION(pixmap,fill) +{ + KviKvsObject *pObject; + kvs_int_t iXoffset,iYoffset; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETER("x_offset",KVS_PT_INT,0,iXoffset) + KVSO_PARAMETER("y_offset",KVS_PT_INT,0,iYoffset) + KVSO_PARAMETERS_END(c) + + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + CHECK_HOBJECT_IS_WIDGET(pObject) + if (m_pAnimatedPixmap) + { + delete m_pAnimatedPixmap; + m_pAnimatedPixmap=0; + } + if(!m_pPixmap) m_pPixmap=new QPixmap(); + m_pPixmap->fill(((QWidget *)(pObject->object())),iXoffset,iYoffset); + return true; +} +KVSO_CLASS_FUNCTION(pixmap,resize) +{ + kvs_int_t iWidth,iHeight; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("width",KVS_PT_INTEGER,0,iWidth) + KVSO_PARAMETER("height",KVS_PT_INTEGER,0,iHeight) + KVSO_PARAMETERS_END(c) + if(m_pPixmap) delete m_pPixmap; + if (m_pAnimatedPixmap){ + delete m_pAnimatedPixmap; + m_pAnimatedPixmap=0; + } + m_pPixmap=new QPixmap(iWidth,iHeight); + return true; +} +KVSO_CLASS_FUNCTION(pixmap,scale) +{ + kvs_int_t iWidth,iHeight; + QString szAspectRatio; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("width",KVS_PT_INTEGER,0,iWidth) + KVSO_PARAMETER("height",KVS_PT_INTEGER,0,iHeight) + KVSO_PARAMETER("aspect_ratio",KVS_PT_STRING,KVS_PF_OPTIONAL,szAspectRatio) + KVSO_PARAMETERS_END(c) + Qt::AspectRatioMode ratio=Qt::KeepAspectRatio; + if(!m_pPixmap || m_pAnimatedPixmap) return true; + if(!szAspectRatio.isEmpty()) + { + if(KviQString::equalCI(szAspectRatio,"IgnoreAspectRatio")) ratio=Qt::IgnoreAspectRatio; + else if (KviQString::equalCI(szAspectRatio,"KeepAspectRatio")) ratio=Qt::KeepAspectRatio; + else if (KviQString::equalCI(szAspectRatio,"KeepAspectRatioByExpanding")) ratio=Qt::KeepAspectRatioByExpanding; + else c->warning(__tr2qs_ctx("Unknown aspect ratio %Q - Switching to KeepAspectRatio ratio","objects"),&szAspectRatio); + } + if (m_pAnimatedPixmap) m_pAnimatedPixmap->resize(QSize(iWidth,iHeight),ratio); + else *m_pPixmap=m_pPixmap->scaled(iWidth,iHeight,ratio,Qt::SmoothTransformation); + return true; +} +KVSO_CLASS_FUNCTION(pixmap,loadAnimation) + +{ + QString szFile; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("file",KVS_PT_STRING,0,szFile) + KVSO_PARAMETERS_END(c) + if(!QFile::exists(szFile)) + { + c->warning(__tr2qs_ctx("I can't find the specified file '%Q'.","objects"),&szFile); + return true; + } + if (m_pAnimatedPixmap) delete m_pAnimatedPixmap; + if (m_pPixmap) + { + delete m_pPixmap; + m_pPixmap=0; + } + m_pAnimatedPixmap= new KviAnimatedPixmap(szFile); + connect(m_pAnimatedPixmap,SIGNAL(frameChanged()),this,SLOT(frameChanged())); + return true; +} + +KVSO_CLASS_FUNCTION(pixmap,startAnimation) +{ + Q_UNUSED(c); + if (m_pAnimatedPixmap) m_pAnimatedPixmap->start(); + return true; +} + +KVSO_CLASS_FUNCTION(pixmap,stopAnimation) +{ + Q_UNUSED(c); + if (m_pAnimatedPixmap) m_pAnimatedPixmap->stop(); + return true; +} + +KVSO_CLASS_FUNCTION(pixmap,load) +{ + QString szFile; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("file",KVS_PT_STRING,0,szFile) + KVSO_PARAMETERS_END(c) + if(!QFile::exists(szFile)) + { + c->warning(__tr2qs_ctx("I can't find the specified file '%Q'.","objects"),&szFile); + return true; + } + if (m_pAnimatedPixmap) delete m_pAnimatedPixmap; + if(!m_pPixmap) m_pPixmap=new QPixmap(); + m_pPixmap->load(szFile); + return true; +} +KVSO_CLASS_FUNCTION(pixmap,save) +{ + QString szFile; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("file",KVS_PT_STRING,0,szFile) + KVSO_PARAMETERS_END(c) + if (m_pAnimatedPixmap) m_pAnimatedPixmap->pixmap()->save(szFile); + else if(m_pPixmap) m_pPixmap->save(szFile); + return true; +} +/* +KVSO_CLASS_FUNCTION(pixmap,save) +{ + //CHECK_INTERNAL_POINTER(m_pPixmap) + QString szFile; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("file",KVS_PT_STRING,0,szFile) + KVSO_PARAMETERS_END(c) + if(!QFile::exists(szFile)) + { + c->warning(__tr2qs_ctx("I can't find the specified file '%Q'.","objects"),&szFile); + return true; + } + if (m_pAnimatedPixmap) delete m_pAnimatedPixmap; + m_pAnimatedPixmap= new KviAnimatedPixmap(szFile); + connect(m_pAnimatedPixmap,SIGNAL(frameChanged()),this,SLOT(frameChanged())); + //bPixmapModified=true; + + return true; +} +*/ +KVSO_CLASS_FUNCTION(pixmap,loadFromMemoryBuffer) +{ + KviKvsObject * pObject; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("hobject",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETERS_END(c) + + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + if (!pObject) + { + c->warning(__tr2qs_ctx("Buffer parameter is not an object","objects")); + return true; + } + if (!pObject->inheritsClass("memorybuffer")) + { + c->warning(__tr2qs_ctx("Buffer parameter is not a memorybuffer object","objects")); + return true; + } + if (m_pAnimatedPixmap){ + delete m_pAnimatedPixmap; + m_pAnimatedPixmap=0; + } + if (!m_pPixmap) m_pPixmap=new QPixmap(); + m_pPixmap->loadFromData(((KvsObject_memoryBuffer *)pObject)->dataBuffer()); + return true; +} + +KVSO_CLASS_FUNCTION(pixmap,grabWidget) +{ + CHECK_INTERNAL_POINTER(m_pPixmap) + KviKvsObject * pObject; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + CHECK_HOBJECT_IS_WIDGET(pObject) + if (m_pAnimatedPixmap){ + delete m_pAnimatedPixmap; + m_pAnimatedPixmap=0; + } + if (!m_pPixmap) m_pPixmap=new QPixmap(); + *m_pPixmap=QPixmap::grabWidget(((KvsObject_widget *)pObject)->widget()); + /* QString szFileName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("file_name",KVS_PT_STRING,0,szFileName) + KVSO_PARAMETERS_END(c) + QPrinter printer;//(QPrinter::HighResolution); + printer.setOutputFormat(QPrinter::PdfFormat); + printer.setPaperSize(QPrinter::A4); + printer.setOutputFileName(szFileName); + + QPixmap pixmap=QPixmap::grabWidget(((QTableWidget *)widget())); + QPainter painter(&printer); + painter.drawPixmap(QPoint(0,0), pixmap, pixmap.rect()); + */ + + return true; +} +KVSO_CLASS_FUNCTION(pixmap,height) +{ + if(!m_pAnimatedPixmap && !m_pPixmap) c->returnValue()->setInteger(0); + else if(m_pAnimatedPixmap) c->returnValue()->setInteger(m_pAnimatedPixmap->size().height()); + else c->returnValue()->setInteger(m_pPixmap->height()); + return true; +} +KVSO_CLASS_FUNCTION(pixmap,width) +{ + if(!m_pAnimatedPixmap && !m_pPixmap) c->returnValue()->setInteger(0); + else if(m_pAnimatedPixmap) c->returnValue()->setInteger(m_pAnimatedPixmap->size().width()); + else c->returnValue()->setInteger(m_pPixmap->width()); + return true; +} + +QPixmap * KvsObject_pixmap::getPixmap() +{ + if (!m_pAnimatedPixmap && !m_pPixmap) return new QPixmap(); + else if(m_pAnimatedPixmap) return m_pAnimatedPixmap->pixmap(); + else return m_pPixmap; +} +KVSO_CLASS_FUNCTION(pixmap,frameChangedEvent) +{ + emitSignal("frameChanged",c); + return true; +} + +// slots +void KvsObject_pixmap::frameChanged() +{ + KviKvsVariantList *params=0; + callFunction(this,"frameChangedEvent",params); +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_pixmap.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES + diff --git a/src/modules/objects/KvsObject_pixmap.h b/src/modules/objects/KvsObject_pixmap.h new file mode 100644 index 000000000..a1e2eeb3a --- /dev/null +++ b/src/modules/objects/KvsObject_pixmap.h @@ -0,0 +1,76 @@ +#ifndef _CLASS_PIXMAP_H_ +#define _CLASS_PIXMAP_H_ +//============================================================================= +// +// File : KvsObject_pixmap.h +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + + +#include +#include +#include +#include +#include "KviCString.h" + + +#include "object_macros.h" + + +class KvsObject_pixmap : public KviKvsObject +{ + Q_OBJECT +// Q_PROPERTY(QPixmap pixmap READ getPixmap) +public: + KVSO_DECLARE_OBJECT(KvsObject_pixmap) + QPixmap * getPixmap(); + + //QPixmap * pixmap(){ return m_pPixmap; } +protected: + KviAnimatedPixmap * m_pAnimatedPixmap; + QPixmap * m_pPixmap; +signals: + void aboutToDie(); +protected: + bool fill(KviKvsObjectFunctionCall *c); + bool resize(KviKvsObjectFunctionCall *c); + bool scale(KviKvsObjectFunctionCall *c); + //bool rotate(KviKvsObjectFunctionCall *c); + bool save(KviKvsObjectFunctionCall *c); + bool startAnimation(KviKvsObjectFunctionCall *c); + bool stopAnimation(KviKvsObjectFunctionCall *c); + bool loadAnimation(KviKvsObjectFunctionCall *c); + bool load(KviKvsObjectFunctionCall *c); + bool height(KviKvsObjectFunctionCall *c); + bool width(KviKvsObjectFunctionCall *c); + bool grabWidget(KviKvsObjectFunctionCall *c); +// bool setOpacity(KviKvsObjectFunctionCall *c); + bool loadFromMemoryBuffer(KviKvsObjectFunctionCall *c); + + bool frameChangedEvent(KviKvsObjectFunctionCall *c); + +protected slots: + void frameChanged(); + }; + +#endif // !_CLASS_PIXMAP_H_ diff --git a/src/modules/objects/KvsObject_popupMenu.cpp b/src/modules/objects/KvsObject_popupMenu.cpp new file mode 100644 index 000000000..25cc28cac --- /dev/null +++ b/src/modules/objects/KvsObject_popupMenu.cpp @@ -0,0 +1,398 @@ +//============================================================================= +// +// File : KvsObject_popupMenu.cpp +// Creation date : Fri Mar 18 21:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include "KvsObject_popupMenu.h" + +#include "KviError.h" +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KviIconManager.h" +#include "KviTalPopupMenu.h" + +#include +#include +#include + + + +/* + @doc: popupmenu + @keyterms: + popupmenu object class, + @title: + popupmenu class + @type: + class + @short: + Provides a popup menu. + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + This widget can be used to display a popup menu.Technically, a popup menu consists of a list of menu items.[br] + You add items with insertItem(). An item is either a string. In addition, items can have an optional icon drawn on the very left side.[br] + @functions: + !fn: $insertItem(,[icon_id:string]) + Inserts menu items into a popup menu with optional icon and return the popup identifier. + !fn: $addMenu() + Sets the popupmenu title to text. + !fn: $exec([,,]) + If called without paramaters show the popup menu at the current pointer position.[br] + With the optional parameters show the popup menu at the coordinate x,y widget parameter relative. + !fn: $removeItem() + Removes the menu item that has the identifier id. + !fn: $removeItemAt() + Removes the menu item at position index. + !fn: $insertSeparator() + Inserts a separator at position index.[br] + If the index is negative the separator becomes the last menu item. + !fn: $activatedEvent() + This function is called when a menu item and return the the item id.[br] + The default implementation emits the [classfnc]$activated[/classfnc]() signal. + !fn: $highligthtedEvent() + This function is called when a menu item is highlighted and return the item id.[br] + The default implementation emits the [classfnc]$highlighted[/classfnc]() signal. + @signals: + !sg: $activated() + This signal is emitted by the default implementation of [classfnc]$activatedEvent[/classfnc](). + !sg: $highlighted() + This signal is emitted by the default implementation of [classfnc]$highlightedEvent[/classfnc](). + [br] + @examples: + [example] + // first we define a class inherited from popupmenu + class(menu,popupmenu) + { + constructor() + { + // we store the item's id for checkit in activatedEvent + @%tile_id=@$insertItem("Tile",118) + @%cascade_id=@$insertItem("Cascade",115) + @$insertSeparator(3) + @%closeactw_id=@$insertItem("Close Active Window",08) + @%closeallw_id=@$insertItem("Close All Window",58) + } + activatedEvent() + { + // now we emit a signals to the relative to the user choice + %id=$0 + if (%id==@%tile_id) @$emit("tile") + else if(%id==@%cascade_id) @$emit("cascade") + else if (%id==@%closeactw_id) @$emit("closeactive") + else @$emit("closeallwindows") + // deleting the popup + delete $$ + } + } + class (ws,widget)[br] + { + #In the constructor we create everything that belong to the single widget. + constructor() + { + #Here we generate a loop to create our labels inside the widget. + %lay=$new(layout,$$) + // we use a vbox to managing labels in vertical orientation + %vb=$new(vbox,$$) + // then add the vbox to the main layout + %lay->$addWidget(%vb,0,0) + // let's create our colorful labels + for(%i=0;%i<15;%i++) + { + @%label=$new(label,%vb) + @%label->$settext("Another class by N\&G") + #We set our foreground's colors using the hex array in a random way. + @%label->$setforegroundcolor($array($rand(255),$rand(255),$rand(255))) + } + } + customContextMenuRequestedEvent() + { + #We create the popupmenu relative to this widget at runtime. + %p=$new(menu,$$) + objects.connect %p tile @$parent tile + objects.connect %p cascade @$parent cascade + objects.connect %p closeactive @$parent closeactivewindow + objects.connect %p closeallwindows @$parent closeallwindows + %p->$exec($$,$($0+10),$($1+10)) + } + } + // we create the workspace widget + %Workspace=$new(workspace) + // we use as space as we have + %size[]=%Workspace->$screenResolution() + // resize it + %Workspace->$resize(%size[0],%size[1]) + // then create 20 subwidget + for(%i=0;%i<20;%i++) + { + %w=$new(ws,%Workspace) + // let's add avery widget to the workspace + %Workspace->$addSubWindow(%w) + // then "shake it" a little bit around :-) + %w->$move($rand($(%size[0]-50)),$rand($(%size[1]-50))) + } + // reimplement closeEvent to delete all this :-) + privateimpl(%Workspace,closeEvent) + { + delete $$ + } + #Let's show! + %Workspace->$show() + [/example] +*/ + +static QHash actionsDict; +static int iIdentifier=0; + + +static int addActionToDict(QAction *pAction) +{ + actionsDict.insert(iIdentifier,pAction); + iIdentifier++; + return (iIdentifier-1); +} +static void removeMenuAllActions(QMenu *pMenu) +{ + QList pActionsList=pMenu->actions(); + QList pActionsListDictValues=actionsDict.values(); + for(int i=0;i=0) actionsDict.remove(actionsDict.key(pActionsList.at(i))); + } +} + +static QAction* getAction(int idx) +{ + return actionsDict.value(idx); +} +static void removeAction(int idx) +{ + actionsDict.remove(idx); +} + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_popupMenu,"popupmenu","widget") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_popupMenu,insertItem) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_popupMenu,setTitle) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_popupMenu,exec) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_popupMenu,insertSeparator) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_popupMenu,removeItem) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_popupMenu,addMenu) + + // events + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_popupMenu,highlightedEvent) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_popupMenu,activatedEvent) + +KVSO_END_REGISTERCLASS(KvsObject_popupMenu) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_popupMenu,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_popupMenu) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_popupMenu) + +KVSO_END_CONSTRUCTOR(KvsObject_popupMenu) + +bool KvsObject_popupMenu::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + SET_OBJECT(QMenu) + connect(widget(),SIGNAL(triggered(QAction *)),this,SLOT(slottriggered(QAction *))); + connect(widget(),SIGNAL(destroyed(QObject *)),this,SLOT(aboutToDie(QObject *))); + connect(widget(),SIGNAL(highlighted(int)),this,SLOT(slothighlighted(int))); + return true; +} + +KVSO_CLASS_FUNCTION(popupMenu,insertItem) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szItem,szIcon; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szItem) + KVSO_PARAMETER("icon_id",KVS_PT_STRING,KVS_PF_OPTIONAL,szIcon) + KVSO_PARAMETERS_END(c) + QPixmap *pix = 0; + QAction * pAction = 0; + if(!szIcon.isEmpty()) + { + pix = g_pIconManager->getImage(szIcon); + if (pix) pAction=((QMenu *)widget())->addAction(*pix,szItem); + else c->warning(__tr2qs_ctx("Icon '%Q' doesn't exist","objects"),&szIcon); + } + else + pAction=((QMenu *)widget())->addAction(szItem); + int identifier=addActionToDict(pAction); + c->returnValue()->setInteger((kvs_int_t)identifier); + return true; +} + +KVSO_CLASS_FUNCTION(popupMenu,setTitle) +{ + QString szTitle; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("title",KVS_PT_STRING,0,szTitle) + KVSO_PARAMETERS_END(c) + if(!widget())return true; + ((QMenu *)widget())->setTitle(szTitle); + + return true; +} + +KVSO_CLASS_FUNCTION(popupMenu,exec) +{ + CHECK_INTERNAL_POINTER(widget()) + if(!c->params()->count()) + { + ((QMenu *)widget())->exec(QCursor::pos()); + return true; + } + + KviKvsObject *pObject; + kvs_uint_t iX,iY; + QString szLabel,szIcon; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETER("x",KVS_PT_UNSIGNEDINTEGER,0,iX) + KVSO_PARAMETER("y",KVS_PT_UNSIGNEDINTEGER,0,iY) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + CHECK_HOBJECT_IS_WIDGET(pObject) + ((QMenu *)widget())->exec(((QWidget *)(pObject->object()))->mapToGlobal(QPoint(iX,iY)) ); + + return true; +} + + + +KVSO_CLASS_FUNCTION(popupMenu,addMenu) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsObject *pObject; + kvs_uint_t iIdx; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("popupmenu",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,KVS_PF_OPTIONAL,iIdx) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + if (!pObject)\ + { + c->warning(__tr2qs_ctx("Popup menu parameter is not an object","objects"));\ + return true; + } + if (!pObject->object())\ + { + c->warning(__tr2qs_ctx("Popup menu parameter is not a valid object","objects"));\ + return true;\ + } + if(!pObject->inheritsClass("popupmenu"))\ + {\ + c->warning(__tr2qs_ctx("Popupmenu object required","objects"));\ + return true;\ + } + QAction *pAction; + if(iIdx) + { + QAction *pActionBefore=actionsDict[iIdx]; + pAction=((QMenu *)widget())->insertMenu(pActionBefore,(QMenu*)pObject->object()); + } + else pAction=((QMenu *)widget())->addMenu((QMenu*)pObject->object()); + int identifier=addActionToDict(pAction); + c->returnValue()->setInteger((kvs_int_t)identifier); + identifier++; + return true; +} + +KVSO_CLASS_FUNCTION(popupMenu,removeItem) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iIdx; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("item_id",KVS_PT_INTEGER,0,iIdx) + KVSO_PARAMETERS_END(c) + QAction * pAction=getAction(iIdx); + if(pAction) + { + ((QMenu *)widget())->removeAction(pAction); + removeAction(iIdx); + } + return true; +} + +KVSO_CLASS_FUNCTION(popupMenu,insertSeparator) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t iIndex; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,iIndex) + KVSO_PARAMETERS_END(c) + QAction * pAction=getAction(iIndex); + if(pAction)((QMenu *)widget())->insertSeparator(pAction); + return true; +} + +void KvsObject_popupMenu::slothighlighted(int i) +{ + KviKvsVariantList params(new KviKvsVariant((kvs_int_t)i)); + callFunction(this,"highlightedEvent",¶ms); +} +void KvsObject_popupMenu::aboutToDie(QObject *pObject) +{ + qDebug("Removing popup from kvs dict"); + removeMenuAllActions((QMenu *)pObject); +} +KVSO_CLASS_FUNCTION(popupMenu,highlightedEvent) +{ + emitSignal("highlighted",c,c->params()); + return true; +} + +void KvsObject_popupMenu::slottriggered(QAction *a) +{ + QHashIterator i(actionsDict); + while (i.hasNext()) + { + i.next(); + if (i.value()== a) break; + } + KviKvsVariantList params(new KviKvsVariant((kvs_int_t)i.key())); + callFunction(this,"activatedEvent",¶ms); +} + +KVSO_CLASS_FUNCTION(popupMenu,activatedEvent) +{ + emitSignal("activated",c,c->params()); + return true; +} + + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_popupMenu.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/objects/KvsObject_popupMenu.h b/src/modules/objects/KvsObject_popupMenu.h new file mode 100644 index 000000000..95e1a023a --- /dev/null +++ b/src/modules/objects/KvsObject_popupMenu.h @@ -0,0 +1,64 @@ +#ifndef _CLASS_POPUPMENU_H_ +#define _CLASS_POPUPMENU_H_ +//============================================================================= +// +// File : KvsObject_popupMenu.h +// Creation date : Fri Mar 18 21:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include "KvsObject_widget.h" +#include "object_macros.h" +#include +#include + + + + +class KvsObject_popupMenu : public KvsObject_widget +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_popupMenu) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool insertItem(KviKvsObjectFunctionCall *c); + bool setTitle(KviKvsObjectFunctionCall *c); + bool addMenu(KviKvsObjectFunctionCall *c); + bool exec(KviKvsObjectFunctionCall *c); + bool removeItem(KviKvsObjectFunctionCall *c); + bool removeItemAt(KviKvsObjectFunctionCall *c); + bool insertSeparator(KviKvsObjectFunctionCall *c); + bool activatedEvent(KviKvsObjectFunctionCall *c); + bool highlightedEvent(KviKvsObjectFunctionCall *c); + +protected slots: + void slottriggered(QAction *); + void slothighlighted(int); + void aboutToDie(QObject *); +}; + +#endif // !_CLASS_POPUPMENU_H_ + diff --git a/src/modules/objects/KvsObject_process.cpp b/src/modules/objects/KvsObject_process.cpp new file mode 100644 index 000000000..7934127c6 --- /dev/null +++ b/src/modules/objects/KvsObject_process.cpp @@ -0,0 +1,323 @@ +//============================================================================= +// +// File : KvsObject_process.cpp +// Creation date : Fri Mar 18 21:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_process.h" +#include "KviError.h" +#include "kvi_debug.h" +#include "kvi_settings.h" +#include "KviLocale.h" +#include "QProcess" + +/* + @doc: process + @keyterms: + process object class, process + @title: + process class + @type: + class + @short: + A class to manage process. + @inherits: + [class]object[/class] + @description: + The Process class is used to start external programs and to communicate with them.[br] + !WARNING AT LAST YOU HAVE TO CLOSE THE PROCESS! + @functions: + !fn: $addArgument() + With this command you give the process name (or more arguments) for comunication. + Es: see the next example. + !fn: $startProcess() + Tries to run the process.[br] + Es: [br] + %process=$new(process);[br] + %process->$addArg("cmd.exe");[br] + %process->$start();[br] + !fn: $readStdout() + Reads the data that the process has written to standard output. + !fn: $readStderr() + Reads the data that the process has written to standard error. + Es:[br] + -------------------Start:[br] + class (test,object)[br] + {[br] + slotReadStdout()[br] + {[br] + %stdo = %Process->$readStdout()[br] + #%Aoutput->$append(%stdo);// coming soon in the new texteditor class[br] + %Aoutput->$settext(%stdo);[br] + }[br] + slotReadStderr()[br] + {[br] + %stderr= %Process->$readStderr()[br] + #%Aoutput->$append(%stderr);// coming soon in the new texteditor class[br] + %Aoutput->$settext(%stderr);[br] + }[br] + }[br] + + %tt=$new(test)[br] + %A=$new(widget)[br] + %A->$setGeometry(100,100,400,300)[br] + %layoutA=$new(layout,%A)[br] + %Ainput=$new(lineedit,%A)[br] + #%Aoutput=$new(textedit,%A)// coming soon in the new texteditor class[br] + %Aoutput=$new(label,%A)[br] + %bclosekill=$new(button,%A)[br] + %bclosekill->$settext("&CloseKill ")[br] + %bkill=$new(button,%A)[br] + %bkill->$settext("&Kill ")[br] + %bterminate=$new(button,%A)[br] + %bterminate->$settext("&Ask to Terminate ")[br] + %layoutA->$addwidget(%Ainput,0,0)[br] + %layoutA->$addwidget(%Aoutput,1,0)[br] + %layoutA->$addwidget(%bclosekill,3,0)[br] + %layoutA->$addwidget(%bkill,4,0,)[br] + %layoutA->$addwidget(%bterminate,5,0)[br] + + %Process=$new(process)[br] + %Process->$addArgument("cmd.exe")[br] + %Process->$startProcess();[br] + + connect %Process readyReadStdout %tt slotReadStdout[br] + connect %Process readyReadStderr %tt slotReadStderr[br] + privateimpl(%Ainput,returnPressedEvent)[br] + { + %command=%Ainput->$text() "\r\n"[br] + %Process->$writeToStdin(%command);[br] + %Ainput->$setText("");[br] + }[br] + + privateimpl(%bclosekill,mousepressevent)[br] + {[br] + %Process->$closekill();[br] + delete %A;[br] + }[br] + privateimpl(%bkill,mousepressevent)[br] + {[br] + %Process->$kill();[br] + delete %A;[br] + }[br] + privateimpl(%bterminate,mousepressevent)[br] + {[br] + %Process->$tryTerminate();[br] + delete %A;[br] + }[br] + %A->$show();[br] + --------------------End.[br] + !fn: $writeToStdin() + Whit this command you send a command to the process: + !fn: $closekill() + This tries to terminate the process the nice way.[br] + If the process is still running after 5 seconds, it terminates the process the hard way.[br] + (I think that this is the better way.)[br] + Es: + %Process->close_kill(); + !fn: $kill() + Kill the process in hard way.(Bad Idea) + !fn: $tryTerminate() + Tries to terminate the process.(It could be well but...) + !fn: $closeStdin() + Close the standard Input. + !fn: $isRunning() + Return 1 if the process is running, else return 0. + !fn: $normalExit() + Returns TRUE if the process has exited normally; otherwise returns FALSE. + !fn: $readyReadStdoutEvent() + This function is invoched by the process when there are new datas.[br] + The default implementation emits the [classfnc]$readyReadStdout[/classfnc]() signal. + !fn: $readyReadStderrEvent() + This function is invoched by the process when there are new error messages.[br] + The default implementation emits the [classfnc]$readyReadStderr[/classfnc]() signal. + + @signals: + !sg: $readyReadStdout() + This signal is emitted by the default implementation of [classfnc]$readyReadStdoutEvent[/classfnc]().[br] + If you reimplement that function you will have to emit the signal manually (if you still need it). + !sg: $readyReadStderr() + This signal is emitted by the default implementation of [classfnc]$readyReadStderrEvent[/classfnc](). +*/ + +KVSO_BEGIN_REGISTERCLASS(KvsObject_process,"process","object") + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_process,addArgument); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_process,startProcess); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_process,readStdout); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_process,readStderr); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_process,writeToStdin); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_process,closekill); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_process,kill); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_process,tryTerminate); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_process,closeStdin); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_process,isRunning); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_process,normalExit); + + // Events + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_process,readyReadStdoutEvent); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_process,readyReadStderrEvent); + + KVSO_END_REGISTERCLASS(KvsObject_process) + + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_process,KviKvsObject) + + m_pProcess = new QProcess(); + connect(m_pProcess,SIGNAL(readyReadStandardOutput()),this,SLOT(slotReadStdout())); + connect(m_pProcess,SIGNAL(readyReadStandardError()),this,SLOT(slotReadStderr())); + +KVSO_END_CONSTRUCTOR(KvsObject_process) + +KVSO_BEGIN_DESTRUCTOR(KvsObject_process) + + delete m_pProcess; + +KVSO_END_CONSTRUCTOR(KvsObject_process) + + + +KVSO_CLASS_FUNCTION(process,addArgument) +{ + + QString szArgument; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("argument",KVS_PT_NONEMPTYSTRING,0,szArgument) + KVSO_PARAMETERS_END(c) + m_szArgs.append(szArgument); + return true; +} + +//->Start the process. +KVSO_CLASS_FUNCTION(process,startProcess) +{ + CHECK_INTERNAL_POINTER(m_pProcess) + QString szcmd; + + szcmd = m_szArgs.takeFirst(); + m_pProcess->start(szcmd, m_szArgs); + + if(m_pProcess->state()==QProcess::NotRunning) + { + c->warning( __tr2qs_ctx("Process could not be started.","objects")); + } + return true; +} +//-->Read the standard output. +KVSO_CLASS_FUNCTION(process,readStderr) +{ + CHECK_INTERNAL_POINTER(m_pProcess) + QString ng_Process = m_pProcess->readAllStandardError(); + c->returnValue()->setString(ng_Process); + return true; +} + +//-->Read the standard error. +KVSO_CLASS_FUNCTION(process,readStdout) +{ + CHECK_INTERNAL_POINTER(m_pProcess) + QString ng_Process =m_pProcess->readAllStandardOutput(); + c->returnValue()->setString(ng_Process); + return true; +} +//-->Signals and slot to manage reading output and error from the process. +KVSO_CLASS_FUNCTION(process,readyReadStdoutEvent) +{ + emitSignal("readyReadStdout",c); + return true; +} + +KVSO_CLASS_FUNCTION(process,readyReadStderrEvent) +{ + emitSignal("readyReadStderr",c); + return true; +} +KVSO_CLASS_FUNCTION(process,writeToStdin) +{ + CHECK_INTERNAL_POINTER(m_pProcess) + QString szCommand; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("command",KVS_PT_STRING,0,szCommand) + KVSO_PARAMETERS_END(c) + if (m_pProcess) m_pProcess->write(szCommand.toUtf8().data()); + return true; +} +//-->The 3 Closing process functions +KVSO_CLASS_FUNCTION(process,closekill) +{ + CHECK_INTERNAL_POINTER(m_pProcess) + //I try to to terminate the process the nice way.... + m_pProcess->terminate(); + //If the process is still running after 5 seconds, I'll terminate the process in the hard way. + QTimer::singleShot( 5000, m_pProcess, SLOT( kill() ) ); + return true; +} +KVSO_CLASS_FUNCTION(process,kill) +{ + CHECK_INTERNAL_POINTER(m_pProcess) + m_pProcess->kill(); + return true; +} +KVSO_CLASS_FUNCTION(process,tryTerminate) +{ + CHECK_INTERNAL_POINTER(m_pProcess) + m_pProcess->terminate(); + return true; +} +//-->Close the standard input. +KVSO_CLASS_FUNCTION(process,closeStdin) +{ + CHECK_INTERNAL_POINTER(m_pProcess) + m_pProcess->closeReadChannel(QProcess::StandardOutput); + return true; +} +//->Returns if the process still runnig +KVSO_CLASS_FUNCTION(process,isRunning) +{ + CHECK_INTERNAL_POINTER(m_pProcess) + c->returnValue()->setBoolean(m_pProcess->state()==QProcess::Running); + return true; +} +//->Returns if the process exited. +KVSO_CLASS_FUNCTION(process,normalExit) +{ + CHECK_INTERNAL_POINTER(m_pProcess) + c->returnValue()->setBoolean(m_pProcess->state()==QProcess::NotRunning && m_pProcess->exitStatus()==QProcess::NormalExit); + return true; +} + +void KvsObject_process::slotReadStdout() +{ + KviKvsVariantList *params=0; + callFunction(this,"readyReadStdoutEvent",params); +} + +void KvsObject_process::slotReadStderr() +{ + KviKvsVariantList *params=0; + callFunction(this,"readyReadStderrEvent",params); +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_process.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES + diff --git a/src/modules/objects/KvsObject_process.h b/src/modules/objects/KvsObject_process.h new file mode 100644 index 000000000..f2726f225 --- /dev/null +++ b/src/modules/objects/KvsObject_process.h @@ -0,0 +1,69 @@ +#ifndef _CLASS_PROCESS_H_ +#define _CLASS_PROCESS_H_ +//============================================================================= +// +// File : KvsObject_process.h +// Creation date : Fri Mar 18 21:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include +#include "KvsObject_widget.h" + + +#include "object_macros.h" +#include "QProcess" + + +class KvsObject_process : public KviKvsObject +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_process) +protected: + QProcess * m_pProcess; +private: + QStringList m_szArgs; +public: + + bool addArgument(KviKvsObjectFunctionCall *c); + bool startProcess(KviKvsObjectFunctionCall *c); + bool readStdout(KviKvsObjectFunctionCall *c); + bool readStderr(KviKvsObjectFunctionCall *c); + bool writeToStdin(KviKvsObjectFunctionCall *c); + bool closekill(KviKvsObjectFunctionCall *c); + bool closeStdin(KviKvsObjectFunctionCall *c); + bool kill(KviKvsObjectFunctionCall *c); + bool tryTerminate(KviKvsObjectFunctionCall *c); + bool normalExit(KviKvsObjectFunctionCall *c); + bool isRunning(KviKvsObjectFunctionCall *c); + + bool readyReadStdoutEvent(KviKvsObjectFunctionCall *c); + bool readyReadStderrEvent(KviKvsObjectFunctionCall *c); + +protected slots: + void slotReadStdout(); + void slotReadStderr(); +}; + + +#endif // !_CLASS_PROCESS_H_ diff --git a/src/modules/objects/KvsObject_progressBar.cpp b/src/modules/objects/KvsObject_progressBar.cpp new file mode 100644 index 000000000..07cddba24 --- /dev/null +++ b/src/modules/objects/KvsObject_progressBar.cpp @@ -0,0 +1,150 @@ +//============================================================================= +// +// File : KvsObject_progressBar.cpp +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_progressBar.h" +#include "KviError.h" +#include "kvi_debug.h" + +#include "KviLocale.h" +#include "KviIconManager.h" +#include + + + + +/* + @doc: progressbar + @keyterms: + progressbar object class, + @title: + progressbar class + @type: + class + @short: + Provides a horizontal progress bar. + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + This widget can be used to display a horizontal progress bar. + @functions: + !fn: $setProgress() + Set the amount of steps completed. + See also [classfnc]$settotalSteps[/classfnc]() + !fn: $settotalSteps() + The progress bar uses the concept of steps; you give it the total number of steps + and the number of steps completed so far and it will display the percentage of steps that have been completed. + See also [classfnc]$setProgress[/classfnc]() + !fn: $reset() + Reset the progress bar. + !fn: $setPercentageVisible() + Sets whether the current progress value is displayed. + See also [classfnc]$isPercentageVisible[/classfnc]() + !fn: $ispercentageVisible() + This property holds whether the current progress value is displayed. + See also [classfnc]$setPercentageVisible[/classfnc]() +*/ + +KVSO_BEGIN_REGISTERCLASS(KvsObject_progressBar,"progressbar","widget") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_progressBar,setProgress) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_progressBar,setFormat) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_progressBar,setTotalSteps) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_progressBar,reset) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_progressBar,setPercentageVisible) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_progressBar,percentageVisible) +KVSO_END_REGISTERCLASS(KvsObject_progressBar) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_progressBar,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_progressBar) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_progressBar) + +KVSO_END_CONSTRUCTOR(KvsObject_progressBar) + +bool KvsObject_progressBar::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + SET_OBJECT (QProgressBar) + return true; +} +KVSO_CLASS_FUNCTION(progressBar,setProgress) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t iValue; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("step_value",KVS_PT_UNSIGNEDINTEGER,0,iValue) + KVSO_PARAMETERS_END(c) + ((QProgressBar *)widget())->setValue(iValue); + return true; +} + +KVSO_CLASS_FUNCTION(progressBar,setTotalSteps) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t iMax; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("total_steps",KVS_PT_UNSIGNEDINTEGER,0,iMax) + KVSO_PARAMETERS_END(c) + ((QProgressBar *)widget())->setMaximum(iMax); + return true; +} + +KVSO_CLASS_FUNCTION(progressBar,reset) +{ + CHECK_INTERNAL_POINTER(widget()) + ((QProgressBar *)widget())->reset(); + return true; +} + + +KVSO_CLASS_FUNCTION(progressBar,setPercentageVisible) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + ((QProgressBar *)widget())->setTextVisible(bEnabled); + return true; +} +KVSO_CLASS_FUNCTION(progressBar,setFormat) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szFormat; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnabled",KVS_PT_STRING,0,szFormat) + KVSO_PARAMETERS_END(c) + ((QProgressBar *)widget())->setFormat(szFormat); + return true; +} +KVSO_CLASS_FUNCTION(progressBar,percentageVisible) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setBoolean(((QProgressBar *)widget())->isTextVisible()); + return true; +} + + diff --git a/src/modules/objects/KvsObject_progressBar.h b/src/modules/objects/KvsObject_progressBar.h new file mode 100644 index 000000000..9b27177e1 --- /dev/null +++ b/src/modules/objects/KvsObject_progressBar.h @@ -0,0 +1,51 @@ +#ifndef _CLASS_PROGRESSBAR_H_ +#define _CLASS_PROGRESSBAR_H_ +//============================================================================= +// +// File : KvsObject_progressBar.h +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include "KvsObject_widget.h" +#include "object_macros.h" + +class KvsObject_progressBar : public KvsObject_widget +{ +public: + KVSO_DECLARE_OBJECT(KvsObject_progressBar) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool setProgress(KviKvsObjectFunctionCall *c); + bool setTotalSteps(KviKvsObjectFunctionCall *c); + bool reset(KviKvsObjectFunctionCall *c); + bool setPercentageVisible(KviKvsObjectFunctionCall *c); + bool percentageVisible(KviKvsObjectFunctionCall *c); + bool setFormat(KviKvsObjectFunctionCall *c); +}; + + +#endif //!_CLASS_PROGRESSBAR_H_ + diff --git a/src/modules/objects/KvsObject_radioButton.cpp b/src/modules/objects/KvsObject_radioButton.cpp new file mode 100644 index 000000000..1b8be1a93 --- /dev/null +++ b/src/modules/objects/KvsObject_radioButton.cpp @@ -0,0 +1,146 @@ +//============================================================================= +// +// File : KvsObject_radioButton.cpp +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_radioButton.h" +#include "KviError.h" +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KviIconManager.h" + +#include +/* + @doc: radiobutton + @keyterms: + radiobutton widget class + @title: + radiobutton class + @type: + class + @short: + A radiobutton class + @inherits: + [class]widget[/class] + @description: + The RadioButton widget provides a radio button with a text or pixmap label. + @functions: + !fn: $settext() + Sets the text that will appear in the radiobutton. + !fn: $isChecked() + Returns 1 (TRUE) if the radio button is checked; otherwise returns 0 (FALSE). + !fn: $setChecked() + Sets whether the radio button is checked to check. + !fn: $setPixmap() + Sets the pixmap shown on the radiobutton..See the [doc:image_id]image identifier[/doc] documentation for the explaination + of the parameter. + !fn: $toggleEvent() + Called by KVIrc when the radibutton state is toggled. + The default implementation emits the toggled() signal. + !sg: $toggled() + This signal is emitted by the default implementation of [classfnc]$toggleEvent[/classfnc]().[br] + + +*/ + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_radioButton,"radiobutton","widget") + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_radioButton,setText) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_radioButton,setChecked) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_radioButton,isChecked) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_radioButton,setImage) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_radioButton,toggleEvent) + +KVSO_END_REGISTERCLASS(KvsObject_radioButton) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_radioButton,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_radioButton) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_radioButton) + +KVSO_END_CONSTRUCTOR(KvsObject_radioButton) + +bool KvsObject_radioButton::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + SET_OBJECT(QRadioButton) + connect(widget(),SIGNAL(toggled(bool)),this,SLOT(toggled(bool))); + return true; +} +KVSO_CLASS_FUNCTION(radioButton,setText) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETERS_END(c) + ((QRadioButton *)widget())->setText(szText); + return true; +} +KVSO_CLASS_FUNCTION(radioButton,isChecked) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setBoolean(((QRadioButton *)widget())->isChecked()); + return true; +} + +KVSO_CLASS_FUNCTION(radioButton,setChecked) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bChecked; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bChecked",KVS_PT_BOOL,0,bChecked) + KVSO_PARAMETERS_END(c) + ((QRadioButton *)widget())->setChecked(bChecked); + return true; +} +KVSO_CLASS_FUNCTION(radioButton,setImage) +{ + CHECK_INTERNAL_POINTER(widget()) + QString icon; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("icon_id",KVS_PT_STRING,0,icon) + KVSO_PARAMETERS_END(c) + QPixmap * pix = g_pIconManager->getImage(icon); + if(pix)((QRadioButton *)widget())->setIcon(*pix); + return true; +} +KVSO_CLASS_FUNCTION(radioButton,toggleEvent) +{ + emitSignal("toggled",c,c->params()); + return true; +} + +void KvsObject_radioButton::toggled(bool b) +{ + KviKvsVariantList params(new KviKvsVariant(b)); + callFunction(this,"toggleEvent",¶ms); +} + + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_radioButton.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES + diff --git a/src/modules/objects/KvsObject_radioButton.h b/src/modules/objects/KvsObject_radioButton.h new file mode 100644 index 000000000..00cdb9f6a --- /dev/null +++ b/src/modules/objects/KvsObject_radioButton.h @@ -0,0 +1,51 @@ +#ifndef _CLASS_RADIOBUTTON_H_ +#define _CLASS_RADIOBUTTON_H_ +//============================================================================= +// +// File : KvsObject_radioButton.h +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_widget.h" +#include "object_macros.h" + +class KvsObject_radioButton : public KvsObject_widget +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_radioButton) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool setText(KviKvsObjectFunctionCall *c); + bool isChecked(KviKvsObjectFunctionCall *c); + bool setChecked(KviKvsObjectFunctionCall *c); + bool setImage(KviKvsObjectFunctionCall *c); + bool toggleEvent(KviKvsObjectFunctionCall *c); +protected slots: + void toggled(bool b); + +}; + +#endif //!_CLASS_RADIOBUTTON_H_ diff --git a/src/modules/objects/KvsObject_slider.cpp b/src/modules/objects/KvsObject_slider.cpp new file mode 100644 index 000000000..7bf2f4923 --- /dev/null +++ b/src/modules/objects/KvsObject_slider.cpp @@ -0,0 +1,301 @@ +//============================================================================= +// +// File : KvsObject_slider.cpp +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_slider.h" +#include "KviError.h" +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KviIconManager.h" + +#include + + +/* +@doc: slider + @keyterms: + slider object class + @title: + slider class + @type: + class + @short: + The slider widget provides a vertical or horizontal slider. + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + The slider is the classic widget for controlling a bounded value.[br] + It lets the user move a slider along a horizontal or vertical groove [br] + and translates the slider's position into an integer value within the legal range.[/classfnc]() + @functions: + !fn: $setOrientation() + Sets the slider's orientation.[br] + Orientation value can be "Horizontal" or "Vertical". + !fn: $setTracking() + Sets whether slider tracking is enabled to enable.[br] + Value can be 1 or 0. + !fn: $setMaxValue() + Sets maximum value for slider's range. + !fn: $setMinValue() + Sets minimum value for slider's range. + !fn: $setLineStep() + Sets the line step to . + !fn: $setPageStep() + Sets the page step to . + !fn: $setTickmarks() + Sets the tickmark settings for this slider.[br] + Values are:[br] + NoMarks - do not draw any tickmarks.[br] + Both - draw tickmarks on both sides of the groove.[br] + Above - draw tickmarks above the (horizontal) slider[br] + Below - draw tickmarks below the (horizontal) slider[br] + Left - draw tickmarks to the left of the (vertical) slider[br] + Right - draw tickmarks to the right of the (vertical) slider + !fn: $setTickInterval() + Sets the interval between tickmarks. + !fn: $value() + Returns slider value. + !fn: $minValue() + Returns slider minValue. + !fn: $maxValue() + Returns slider maxValue. + !fn: $lineStep() + Returns slider lineStep value. + !fn: $pageStep() + Returns slider pageStep value. + !fn: $valueChangedEvent() + This function is called by the framework when the slider value is changed and return the new slider value as its argument.[br] + The default implementation emits the [classfnc]$valueChanged[/classfnc]() signal, + so it is easy to handle the values from many sliders without reimplementing + the [classfnc]$valueChangedEvent[/classfnc]() for every one.[br] + Note: If you reimplement this function to catch the slider value, you will have to emit the signal by yourself (if you still need it, obviously). + @signals: + !sg: $valueChanged() + This signal is emitted by the default implementation of [classfnc]valueChangedEvent[/classfnc]().[br] + If you reimplement that function you will have to emit the signal manually (if you still need it). + +*/ + + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_slider,"slider","widget") + + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_slider,setTracking); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_slider,setValue); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_slider,setMinValue); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_slider,setMaxValue); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_slider,setLineStep); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_slider,setPageStep); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_slider,setTickInterval); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_slider,value); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_slider,minValue); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_slider,maxValue); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_slider,lineStep); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_slider,pageStep); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_slider,setTickmarks); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_slider,setOrientation); + + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_slider,valueChangedEvent); +KVSO_END_REGISTERCLASS(KvsObject_slider) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_slider,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_slider) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_slider) + +KVSO_END_CONSTRUCTOR(KvsObject_slider) + +bool KvsObject_slider::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + SET_OBJECT(QSlider) + connect(widget(),SIGNAL(valueChanged(int)),this,SLOT(valueChanged(int))); + return true; +} + +KVSO_CLASS_FUNCTION(slider,setTracking) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + ((QSlider *)widget())->setTracking(bEnabled); + return true; +} + + +KVSO_CLASS_FUNCTION(slider,setValue) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iValue; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("value",KVS_PT_INT,0,iValue) + KVSO_PARAMETERS_END(c) + ((QSlider *)widget())->setValue(iValue); + return true; +} +KVSO_CLASS_FUNCTION(slider,setMinValue) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iMinvalue; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("minimum_value",KVS_PT_INT,0,iMinvalue) + KVSO_PARAMETERS_END(c) + ((QSlider *)widget())->setMinimum(iMinvalue); + return true; +} +KVSO_CLASS_FUNCTION(slider,setMaxValue) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iMaxvalue; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("max_value",KVS_PT_INT,0,iMaxvalue) + KVSO_PARAMETERS_END(c) + ((QSlider *)widget())->setMaximum(iMaxvalue); + return true; +} + +KVSO_CLASS_FUNCTION(slider,setLineStep) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iLinestep; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("line_step",KVS_PT_INT,0,iLinestep) + KVSO_PARAMETERS_END(c) + ((QSlider *)widget())->setSingleStep(iLinestep); + return true; +} +KVSO_CLASS_FUNCTION(slider,setPageStep) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iPagestep; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("page_step",KVS_PT_INT,0,iPagestep) + KVSO_PARAMETERS_END(c) + if (widget()) ((QSlider *)widget())->setPageStep(iPagestep); + return true; +} + +KVSO_CLASS_FUNCTION(slider,setTickInterval) +{ + kvs_int_t iInterval; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("tick_interval",KVS_PT_INT,0,iInterval) + KVSO_PARAMETERS_END(c) + ((QSlider *)widget())->setTickInterval(iInterval); + return true; +} + +KVSO_CLASS_FUNCTION(slider,value) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QSlider *)widget())->value()); + return true; +} + +KVSO_CLASS_FUNCTION(slider,minValue) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QSlider *)widget())->minimum()); + return true; +} +KVSO_CLASS_FUNCTION(slider,maxValue) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QSlider *)widget())->maximum()); + return true; +} +KVSO_CLASS_FUNCTION(slider,lineStep) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QSlider *)widget())->singleStep()); + return true; +} + +KVSO_CLASS_FUNCTION(slider,pageStep) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QSlider *)widget())->pageStep()); + return true; +} + + +KVSO_CLASS_FUNCTION(slider,setTickmarks) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szTick; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("tick_marks",KVS_PT_STRING,0,szTick) + KVSO_PARAMETERS_END(c) + if(KviQString::equalCI(szTick,"NoMarks")) + ((QSlider *)widget())->setTickPosition(QSlider::NoTicks); + else if(KviQString::equalCI(szTick,"Both")) + ((QSlider *)widget())->setTickPosition(QSlider::TicksBothSides); + else if(KviQString::equalCI(szTick,"Above")) + ((QSlider *)widget())->setTickPosition(QSlider::TicksAbove); + else if(KviQString::equalCI(szTick,"Below")) + ((QSlider *)widget())->setTickPosition(QSlider::TicksBelow); + else if(KviQString::equalCI(szTick,"Left")) + ((QSlider *)widget())->setTickPosition(QSlider::TicksLeft); + else if(KviQString::equalCI(szTick,"Right")) + ((QSlider *)widget())->setTickPosition(QSlider::TicksRight); + else c->warning( __tr2qs_ctx("Unknown tickmark '%Q'","objects"),&szTick); + return true; +} +KVSO_CLASS_FUNCTION(slider,setOrientation) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szOrientation; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("orientation",KVS_PT_STRING,0,szOrientation) + KVSO_PARAMETERS_END(c) + if(KviQString::equalCI(szOrientation,"Horizontal")) + ((QSlider *)widget())->setOrientation(Qt::Horizontal); + else if(KviQString::equalCI(szOrientation,"Vertical")) + ((QSlider *)widget())->setOrientation(Qt::Vertical); + else c->warning( __tr2qs_ctx("Unknown orientation '%Q'","objects"),&szOrientation); + return true; +} +KVSO_CLASS_FUNCTION(slider,valueChangedEvent) +{ + emitSignal("valueChanged",c,c->params()); + return true; +} + +void KvsObject_slider::valueChanged(int value) +{ + KviKvsVariantList params(new KviKvsVariant((kvs_int_t)value)); + callFunction(this,"valueChangedEvent",¶ms); +} + + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_slider.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES + diff --git a/src/modules/objects/KvsObject_slider.h b/src/modules/objects/KvsObject_slider.h new file mode 100644 index 000000000..7474d0db0 --- /dev/null +++ b/src/modules/objects/KvsObject_slider.h @@ -0,0 +1,64 @@ +#ifndef _CLASS_SLIDER_H_ +#define _CLASS_SLIDER_H_ +//============================================================================= +// +// File : KvsObject_slider.h +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_widget.h" +#include "object_macros.h" + +class KvsObject_slider : public KvsObject_widget +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_slider) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool setTracking(KviKvsObjectFunctionCall *c); + bool setValue(KviKvsObjectFunctionCall *c); + bool setMinValue(KviKvsObjectFunctionCall *c); + bool setMaxValue(KviKvsObjectFunctionCall *c); + bool setLineStep(KviKvsObjectFunctionCall *c); + bool setPageStep(KviKvsObjectFunctionCall *c); + bool setTickInterval(KviKvsObjectFunctionCall *c); + bool value(KviKvsObjectFunctionCall *c); + bool minValue(KviKvsObjectFunctionCall *c); + bool maxValue(KviKvsObjectFunctionCall *c); + bool lineStep(KviKvsObjectFunctionCall *c); + bool pageStep(KviKvsObjectFunctionCall *c); + bool setTickmarks(KviKvsObjectFunctionCall *c); + bool setOrientation(KviKvsObjectFunctionCall *c); + bool valueChangedEvent(KviKvsObjectFunctionCall *c); + +protected slots: + void valueChanged(int); +}; + + + +#endif // !_CLASS_SLIDER_H_ + diff --git a/src/modules/objects/KvsObject_socket.cpp b/src/modules/objects/KvsObject_socket.cpp new file mode 100644 index 000000000..6c40f8ea2 --- /dev/null +++ b/src/modules/objects/KvsObject_socket.cpp @@ -0,0 +1,1297 @@ +//============================================================================= +// +// File : KvsObject_socket.cpp +// Creation date : Sun Nov 11 03:13:45 2001 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_socket.h" +#include "KvsObject_memoryBuffer.h" +#include "KvsObject_file.h" + +#include "kvi_settings.h" +#include "KviQString.h" + +#define _KVI_DEBUG_CHECK_RANGE_ +#include "kvi_debug.h" + +#include "KviFile.h" +#include "KviFileUtils.h" +#include "KviLocale.h" +#include "KviError.h" +#include "KviNetUtils.h" +#include "KviDnsResolver.h" +#include "KviError.h" +#include "kvi_socket.h" +#include "KviMemory.h" +#include "KviMemory.h" +#include "KviDataBuffer.h" + +#include + +//#include + +#define KVI_IN_BUFFER_ALLOC_CHUNK 4096 +#define KVI_READ_CHUNK 1024 + +/* + @doc: socket + @keyterms: + socket object class + @title: + socket class + @type: + class + @short: + A Ipv4/Ipv6 TCP socket + @inherits: + [class]object[/class] + @description: + This class provides a standard TCP/IP socket functionality.[br] + It can be used either for connecting to a remote host or to listening for incoming connections.[br] + If the KVIrc executable has been compiled with the IPV6 protocol support, this socket also supports it.[br] + @functions: + !fn: $status() + Returns the status of the socket :[br] + 4=connected[br] + 3=listening[br] + 2=connecting[br] + 1=in dns call[br] + 0=disconnected + + !fn: $connectTimeout() + Returns the value of the connect attempt timeout in milliseconds.[br] + This is the timeout after that a connection attempt will be considered as failed if the remote + host is not responding. You can set it with [classfnc:socket]$setConnectTimeout[/classfnc](). + + !fn: $setConnectTimeout() + Sets the connect timeout for this socket. must be a positive value in milliseconds.[br] + The default timeout is 60000. + + !fn: $connect(,) + Attempts a connection to on port .[br] + can be a numeric internet address (either Ipv4 or Ipv6 (if supported)) or a hostname.[br] + If a hostname is used, a DNS lookup is performed (the socket enters the "dns call" state).[br] + This function returns 1 if the connect attempt can be successfully initiated, + 0 otherwise.[br] In fact, this function returns 0 only if the supplied parameter + is invalid or the socket is in an incoherent state (already connected or listening): + for a newly created socket and with a valid number you can safely ignore + the return value.[br] + Please note that the connection is asynchronous: when this function returns + the socket is NOT connected: it has just initiated the connect attempt + and you will be notified of the attempt result by an asynchronous event call: + in case of failure, $connectFailedEvent() will be called, in case of + succes, $connectEvent() will be called. + + !fn: $listen([[,[,]]]) + Attempts to listen on the specified and .[br] + If is not passed it is assumed to be 0, if is not passed, it is assumed to be + "any interface" (INADDR_ANY).[br] Port 0 means that the kernel should choose a "random" port to listen on.[br] + If the is recognized as IPV6 address, and IPV6 is supported, the socket listens + in IPV6 mode. If is an empty string and is 1 the socket listens + on "any ipv6 interface".[br] + This function returns '1' in case of success and '0' in case of failure.[br] + On some systems listening in the IPV6 namespace allows to accept also IPV4 connections (this includes + linux but not windows afaik).[br] + When an incoming connection will arrive, $incomingConnectionEvent() will be called. + + !fn: $accept() + This function can be called only from inside $incomingConnectionEvent().[br] + must be a newly created socket sub-class instance object.[br] + The passed object will be set up to handle the incoming connection and this object + will remain in listening state (unless you explicitly close it).[br] + This function returns '1' in case of success and '0' in case of failure. + + !fn: $connectEvent() + This function is called when a connection attempt has been successfully completed. + The socket is actually connected to [classfnc:socket]$remoteIp[/classfnc]() on + [classfnc:socket]$remotePort[/classfnc](). You can start + writing data and you may expect [classfnc:socket]$dataAvailableEvent[/classfnc]() to be + triggered. + + !fn: $incomingConnectionEvent() + This function is called when an incoming connection arrives over a socket in listening state.[br] + You must call [classfnc:socket]$accept[/classfnc]() passing a newly created socket object + to accept and handle the connection.[br] If you don't call [classfnc:socket]$accept[/classfnc]() + the incoming connection will be automatically terminated. + + !fn: $connectFailedEvent() + This function is called when a connection attempt fails for some reason. contains + the error string.[br] + This function may be called only between a call to [classfnc:socket]$connect[/classfnc]() and + the [classfnc:socket]$connectEvent[/classfnc](). + + !fn: $disconnectEvent([error]) + This function is called when a connection is terminated either cleanly or because of an error.[br] + [error] is an empty string in case of a "clean" termination (connection closed by the remote host) + or is a message describing the socket error that caused the connection to be interrupted. + + !fn: $dataAvailableEvent() + This function is called when some data is available to be read: the parameter specifies + the length of the available data in bytes.[br] + You can use one of the $read* functions to obtain the data. + + !fn: $read([,]) + Reads at most bytes of data from the socket. If is anything "outside" the + available data range ( < 0 or > available_data_length), this function + returns all the available data.[br] + By default this function can deal ascii data only: NULL characters are transformed to + ASCII characters 255. You can pass a [class]memorybuffer[/class] object to read binary data. + + !fn: $write([,length]) + Writes to the socket.[br] + This function can deal with binary data passing a [class]memorybuffer[/class] object[br] + Please note that when this function finishes it does not mean that the data has reached the remote end.[br] + Basically it does not even mean that the data has been sent to the remote host.[br] + The data is enqueued for sending and will be sent as soon as possible.[br] + Using an array you can pass bytes or data string like this: @$write($array($(0xff),$(0xff),$(0xff),$(0xff),"This is an example")); + If you're going to [cmd]delete[/cmd] this object just after the $write call, you should + call [classfnc:socket]$close[/classfnc]() just before [cmd]delete[/cmd] to ensure the data delivery. + + !fn: $close() + Resets this socket state: kills any pending or active connection. After a close() call + the socket may be used for a new connection.[br] + If there is an active connection, there is a last attempt to flush the pending outgoing data.[br] + You don't need to call $close() if you [cmd]delete[/cmd] the socket: KVIrc will + reset the socket state automatically and free the memory. But if you want to ensure data delivery + after a $write call sequece and just before a [cmd]delete[/cmd], $close() is the only chance to do it. + + !fn: $remoteIp() + Returns the IP address of the remote end of this socket.[br] + The return value is meaningful only if the socket is in connected or connecting state. + + !fn: $setProtocol() + Let KVIrc use TCP or UDP protocol + + !fn: $remotePort() + Returns the port of the remote end of this socket.[br] + The return value is meaningful only if the socket is in connected or connecting state. + + !fn: $localIp() + Returns the IP address of the local end of this socket.[br] + The return value is meaningful only if the socket is in connected, listening or connecting state. + + !fn: $localPort() + Returns the port of the local end of this socket.[br] + The return value is meaningful only if the socket is in connected, listening or connecting state. + +@examples: + [example] + // Server socket: listen 8080 port and answer to requests (multi-threaded) + class (webserver,socket) + { + constructor () + { + @$listen(8080, "127.0.0.1") + } + incomingConnectionEvent() + { + %tmp = $new(socket) + @$accept(%tmp) + echo "Webserver incoming Conection from: %tmp->$remoteIp : %tmp->$remotePort" + %tmp->$write("HTTP/1.1 200 OK\n\n

KVIrc Webserver

\n") + %tmp->$close() + delete %tmp + } + } + // finally start webserver + %WebS = $new(webserver) + [/example] + [example] + // Client socket - go to google and grab request header[br] + class (httprequest,socket) + { + constructor () + { + // connect to the server + @$connect("www.google.com",80) + } + destructor() + { + // if the socket is still open close it + if(@$status() == 4) @$close() + } + connectFailedEvent() + { + // the connection to the server failed + debug "Connection failed: "$0 + delete $$ + } + connectEvent() + { + // connection is complete + // send a request to receive the headers only from http://www.google.com/ + @$write("HEAD / HTTP/1.1\r\nHost: www.google.de\r\nConnction: Close\r\nUser-Agent: KVIrc socket\r\n\r\n"); + } + dataAvailableEvent() + { + // reading the received data + %newdata = @$read($0) + echo %newdata + #close and delete the socket + @$close() + delete $$ + } + disconnectEvent() + { + // connection has been closed + echo "Connection closed" + delete $$ + } + } + %Temp = $new(httprequest) + [/example] +*/ + +KVSO_BEGIN_REGISTERCLASS(KvsObject_socket,"socket","object") + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_socket,status) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_socket,remotePort) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_socket,remoteIp) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_socket,localIp) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_socket,localPort) + KVSO_REGISTER_HANDLER(KvsObject_socket,"connect",functionConnect) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_socket,connectTimeout) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_socket,setConnectTimeout) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_socket,close) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_socket,read) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_socket,write) + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_socket,setProtocol) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_socket,listen) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_socket,accept) + + KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KvsObject_socket,"connectEvent") + KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KvsObject_socket,"connectFailedEvent") + KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KvsObject_socket,"disconnectEvent") + KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KvsObject_socket,"dataAvailableEvent") + KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KvsObject_socket,"incomingConnectionEvent") + +KVSO_END_REGISTERCLASS(KvsObject_socket) + + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_socket,KviKvsObject) + m_bUdp = false; + m_uConnectionId = 0; + m_sock = KVI_INVALID_SOCKET; + m_iStatus = KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED; + m_uRemotePort = 0; + m_uSecondaryPort = 0; + m_pSn = 0; + m_pDns = 0; + m_pDelayTimer = 0; + m_uConnectTimeout = 60000; + m_pInBuffer = 0; + m_uInBufferLen = 0; + m_uInDataLen = 0; + m_pOutBuffer = new KviDataBuffer(); + m_pFlushTimer = new QTimer(); + m_bIPv6 = false; + m_uLocalPort = 0; + m_secondarySock = KVI_INVALID_SOCKET; + connect(m_pFlushTimer,SIGNAL(timeout()),this,SLOT(tryFlush())); +KVSO_END_CONSTRUCTOR(KvsObject_socket) + +KVSO_BEGIN_DESTRUCTOR(KvsObject_socket) + delete m_pOutBuffer; + delete m_pFlushTimer; + m_pOutBuffer=0; + m_pFlushTimer=0; + + + if(m_pInBuffer)KviMemory::free(m_pInBuffer); + if(m_pDelayTimer)delete m_pDelayTimer; + if(m_pDns)delete m_pDns; + if(m_pSn)delete m_pSn; + if(m_sock != KVI_INVALID_SOCKET)kvi_socket_close(m_sock); + if(m_secondarySock != KVI_INVALID_SOCKET)kvi_socket_close(m_secondarySock); +KVSO_END_DESTRUCTOR(KvsObject_socket) +//---------------------- + + +KVSO_CLASS_FUNCTION(socket,status) +{ + c->returnValue()->setInteger(m_iStatus); + return true; +} + +KVSO_CLASS_FUNCTION(socket,close) +{ + Q_UNUSED(c); + + if (!m_pOutBuffer) return true; + if((m_pOutBuffer->size() != 0) && (m_iStatus == KVI_SCRIPT_SOCKET_STATUS_CONNECTED)) + tryFlush(); + + reset(); + return true; +} + +KVSO_CLASS_FUNCTION(socket,connectTimeout) +{ + c->returnValue()->setInteger(m_uConnectTimeout); + return true; +} + +KVSO_CLASS_FUNCTION(socket,setConnectTimeout) +{ + kvs_uint_t uTimeout; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("time_out",KVS_PT_UNSIGNEDINTEGER,0,uTimeout) + KVSO_PARAMETERS_END(c) + m_uConnectTimeout = uTimeout; + return true; +} + +KVSO_CLASS_FUNCTION(socket,remotePort) +{ + c->returnValue()->setInteger(m_uRemotePort); + return true; +} + +KVSO_CLASS_FUNCTION(socket,remoteIp) +{ + c->returnValue()->setString(m_szRemoteIp); + return true; +} + +KVSO_CLASS_FUNCTION(socket,localPort) +{ + c->returnValue()->setInteger(m_uLocalPort); + return true; +} + +KVSO_CLASS_FUNCTION(socket,localIp) +{ + c->returnValue()->setString(m_szLocalIp); + return true; +} + +unsigned int KvsObject_socket::readGetLength(KviKvsObjectFunctionCall * c) +{ + kvs_uint_t uLen; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("length",KVS_PT_UNSIGNEDINTEGER,KVS_PF_OPTIONAL,uLen) + KVSO_PARAMETERS_END(c) + if (uLen>m_uInDataLen || !uLen) return m_uInDataLen; + else return uLen; +} + +KVSO_CLASS_FUNCTION(socket,read) +{ + kvs_uint_t uLen; + KviKvsObject * pObject; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("length",KVS_PT_UNSIGNEDINTEGER,KVS_PF_OPTIONAL,uLen) + KVSO_PARAMETER("hobject",KVS_PT_HOBJECT,KVS_PF_OPTIONAL,hObject) + KVSO_PARAMETERS_END(c) + if (uLen>m_uInDataLen || !uLen) uLen=m_uInDataLen; + if (hObject) + { + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + if(!pObject) + { + c->warning(__tr2qs_ctx("Buffer parameter is not an object","objects")); + return true; + } + if(pObject->inheritsClass("memorybuffer")) + { + QByteArray *pBuffer=((KvsObject_memoryBuffer *)pObject)->pBuffer(); + int oldsize=pBuffer->size(); + pBuffer->resize(oldsize+uLen); + KviMemory::move(pBuffer->data()+oldsize,m_pInBuffer,uLen); + + } else if(pObject->inheritsClass("file")) + { + KviFile *pFile=((KvsObject_file *)pObject)->file(); + if (!pFile->isOpen()) + { + c->warning(__tr2qs_ctx("File is not open!","objects")); + return true; + } + pFile->write(m_pInBuffer,uLen); + } else + { + c->warning(__tr2qs_ctx("Buffer parameter is not a memorybuffer object","objects")); + return true; + } + eatInData(uLen); + return true; + } + if(uLen > 0) + { + // convert NULLS to char 255 + for(unsigned int i = 0;i < uLen;i++) + { + if(!m_pInBuffer[i])m_pInBuffer[i] = (char)(255); + } + QString tmpBuffer = QString::fromUtf8(m_pInBuffer,uLen); + c->returnValue()->setString(tmpBuffer); + + eatInData(uLen); + } + return true; +} + + + +KVSO_CLASS_FUNCTION(socket,write) +{ + kvs_uint_t uLen; + KviKvsObject * pObject; + KviKvsVariant * pVariantData; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("data_or_file_or_memorybuffer",KVS_PT_VARIANT,0,pVariantData) + KVSO_PARAMETER("length",KVS_PT_UNSIGNEDINTEGER,KVS_PF_OPTIONAL,uLen) + KVSO_PARAMETERS_END(c) + if (pVariantData->isHObject()) + { + pVariantData->asHObject(hObject); + pObject = KviKvsKernel::instance()->objectController()->lookupObject(hObject); + if(!pObject) + { + c->warning(__tr2qs_ctx("Buffer parameter is not an object","objects")); + return true; + } + if(pObject->inheritsClass("memorybuffer")) + { + QByteArray *p=((KvsObject_memoryBuffer *)pObject)->pBuffer(); + m_pOutBuffer->append((const unsigned char *)p->data(),p->size()); + } else if(pObject->inheritsClass("file")) + { + KviFile * pFile = ((KvsObject_file *)pObject)->file(); + if(!pFile->isOpen()) + { + c->warning(__tr2qs_ctx("File is not open!","objects")); + return true; + } + if(!uLen) + uLen = pFile->size(); + kvs_int_t size = pFile->size(); + pFile->flush(); + m_pOutBuffer->append((const unsigned char*)pFile->read(uLen).data(),uLen); + c->returnValue()->setBoolean((size-pFile->pos()==0)); + } else { + c->warning(__tr2qs_ctx("Buffer parameter is not a memorybuffer or file object","objects")); + return true; + } + } else { + if(pVariantData->isArray()) + { + KviKvsArray * pArray = pVariantData->array(); + for(unsigned int i=0; i < pArray->size(); i++) + { + KviKvsVariant * pVar = pArray->at(i); + kvs_int_t iValue; + if(pVar->asInteger(iValue)) + { + if(iValue < 256 && iValue >= 0) + { + m_pOutBuffer->append((unsigned char)iValue); + continue; + } else { + c->warning(__tr2qs_ctx("Only values in the range of 0-255 are allowed: integer %d is out of range","objects"),iValue); + return true; + } + } else { + if(pVar->isString()) + { + QString szData; + pVar->asString(szData); + QByteArray szData8 = szData.toUtf8(); + m_pOutBuffer->append((const unsigned char*)szData8.data(),szData8.length()); + } else { + c->warning(__tr2qs_ctx("Datatype not supported","objects")); + return true; + } + } + } + delayedFlush(0); + return true; + } + + QString szData; + pVariantData->asString(szData); + if(!KviFileUtils::fileExists(szData)) + { + QByteArray szData8 = szData.toUtf8(); + if(szData8.length() > 0) + { + qDebug("write on socket %s",szData8.data()); + m_pOutBuffer->append((const unsigned char*)szData8.data(),szData8.length()); + } + } else { + KviFile f(szData); + f.open(QIODevice::ReadOnly); + QByteArray ar = f.readAll(); + m_pOutBuffer->append((const unsigned char*)ar.data(),ar.size()); + f.close(); + } + } + delayedFlush(0); + return true; +} + + +KVSO_CLASS_FUNCTION(socket,accept) +{ + KviKvsObject * pObject; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("object_socket",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETERS_END(c) + + pObject = KviKvsKernel::instance()->objectController()->lookupObject(hObject); + + if(!pObject) + { + c->warning(__tr2qs_ctx("No socket object specified","objects")); + return true; + } + + if(!pObject->inheritsClass("socket")) + { + c->warning(__tr2qs_ctx("Invalid socket object specified (it doesn't inherit from socket)","objects")); + return true; + } + + if(m_secondarySock != KVI_INVALID_SOCKET) + { + ((KvsObject_socket *)pObject)->acceptConnection(m_secondarySock,m_uSecondaryPort,m_szSecondaryIp.toUtf8().data()); + + m_secondarySock = KVI_INVALID_SOCKET; + m_uSecondaryPort = 0; + m_szSecondaryIp=""; + } else { + c->warning(__tr2qs_ctx("There is no connection to accept!","objects")); + } + return true; +} + + +KVSO_CLASS_FUNCTION(socket,setProtocol) +{ + QString szProto; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("protocol",KVS_PT_STRING,0,szProto) + KVSO_PARAMETERS_END(c) + + m_bUdp = KviQString::equalCI(szProto,"udp"); + return true; +} + +KVSO_CLASS_FUNCTION(socket,functionConnect) +{ + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("remote_ip",KVS_PT_STRING,0,m_szRemoteIp) + KVSO_PARAMETER("remote_port",KVS_PT_UNSIGNEDINTEGER,0,m_uRemotePort) + KVSO_PARAMETERS_END(c) + qDebug("Function connect"); + + if (m_uRemotePort>65535) + { + c->warning(__tr2qs_ctx("Value %d for port is out of range (values allowed are from 0 to 65535)","objects"),m_uRemotePort); + return true; + } + if((m_sock != KVI_INVALID_SOCKET) || (m_iStatus != KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED)) + { + c->warning(__tr2qs_ctx("Another connection in progress","objects")); + c->returnValue()->setBoolean(true); + return true; + } + + +#ifdef COMPILE_IPV6_SUPPORT + if(KviNetUtils::isValidStringIp(m_szRemoteIp) || KviNetUtils::isValidStringIPv6(m_szRemoteIp)) +#else + if(KviNetUtils::isValidStringIp(m_szRemoteIp)) +#endif + { + qDebug("ok connecting"); + qDebug("connecting to ip %s ",m_szRemoteIp.toUtf8().data()); + qDebug("no ip"); + m_iStatus = KVI_SCRIPT_SOCKET_STATUS_CONNECTING; + delayedConnect(); + } else { + qDebug("connecting on ip %s port %d",m_szRemoteIp.toUtf8().data(),(int) m_uRemotePort); + m_iStatus = KVI_SCRIPT_SOCKET_STATUS_DNS; + delayedLookupRemoteIp(); + } + c->returnValue()->setBoolean(true); + return true; +} + + +KVSO_CLASS_FUNCTION(socket,listen) +{ + if((m_sock != KVI_INVALID_SOCKET) || (m_iStatus != KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED)) + { + c->warning(__tr2qs_ctx("Another connection in progress","objects")); + c->returnValue()->setBoolean(false); + return true; + } + kvs_uint_t uLocalPort; + QString m_szLocalIp; + bool m_bIPv6; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("local_port",KVS_PT_UNSIGNEDINTEGER,0,uLocalPort) + KVSO_PARAMETER("local_ip",KVS_PT_STRING,KVS_PF_OPTIONAL,m_szLocalIp) + KVSO_PARAMETER("bool_ipV6",KVS_PT_BOOLEAN,KVS_PF_OPTIONAL,m_bIPv6) + KVSO_PARAMETERS_END(c) + m_uLocalPort=uLocalPort; + +#ifndef COMPILE_IPV6_SUPPORT + if(m_bIPv6) + { + c->warning(__tr2qs_ctx("No IPv6 support in this executable","objects")); + c->returnValue()->setBoolean(false); + reset(); + return true; + } +#endif + + if(!m_szLocalIp.isEmpty()) + { + + // Check the address type + if(!KviNetUtils::isValidStringIp(m_szLocalIp)) + { +#ifdef COMPILE_IPV6_SUPPORT + if(KviNetUtils::isValidStringIPv6(m_szLocalIp)) + { + m_bIPv6 = true; + } else { +#else + c->warning(__tr2qs_ctx("Invalid IP address (%Q)","objects"),&m_szLocalIp); + c->returnValue()->setBoolean(false); + reset(); + return true; +#endif +#ifdef COMPILE_IPV6_SUPPORT + } +#endif + } + } + + +#ifdef COMPILE_IPV6_SUPPORT + m_sock = kvi_socket_create(m_bIPv6 ? KVI_SOCKET_PF_INET6 : KVI_SOCKET_PF_INET, + m_bUdp ? KVI_SOCKET_TYPE_DGRAM : KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); +#else + m_sock = kvi_socket_create(KVI_SOCKET_PF_INET,m_bUdp ? KVI_SOCKET_TYPE_DGRAM : KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); +#endif + + if(m_sock == KVI_INVALID_SOCKET) + { + c->warning(__tr2qs_ctx("Socket creation failed","objects")); + c->returnValue()->setBoolean(false); + reset(); + return true; + } + + if(!m_szLocalIp.isEmpty()) + { +#ifdef COMPILE_IPV6_SUPPORT + KviSockaddr sa(m_szLocalIp.toUtf8().data(),m_uLocalPort,m_bIPv6,m_bUdp); +#else + KviSockaddr sa(m_szLocalIp.toUtf8().data(),m_uLocalPort,false,m_bUdp); +#endif + if(!sa.socketAddress()) + { + c->warning(__tr2qs_ctx("Invalid socket address","objects")); + reset(); + c->returnValue()->setBoolean(false); + return true; + } + + if(!kvi_socket_bind(m_sock,sa.socketAddress(),((int)(sa.addressLength())))) + { + c->warning(__tr2qs_ctx("Bind failure","objects")); + reset(); + c->returnValue()->setBoolean(false); + return true; + } + } else { +#ifdef COMPILE_IPV6_SUPPORT + KviSockaddr sa(m_uLocalPort,m_bIPv6,m_bUdp); +#else + KviSockaddr sa(m_uLocalPort,false,m_bUdp); +#endif + if(!sa.socketAddress()) + { + c->warning(__tr2qs_ctx("Invalid socket address","objects")); + reset(); + c->returnValue()->setBoolean(false); + return true; + } + + if(!kvi_socket_bind(m_sock,sa.socketAddress(),((int)(sa.addressLength())))) + { + c->warning(__tr2qs_ctx("Bind failure","objects")); + reset(); + c->returnValue()->setBoolean(false); + return true; + } + } + + if(!kvi_socket_listen(m_sock,5)) + { + c->warning(__tr2qs_ctx("Listen failure","objects")); + reset(); + c->returnValue()->setBoolean(false); + return true; + } + + + // Reread the port in case we're binding to a random one (0) + +#ifdef COMPILE_IPV6_SUPPORT + KviSockaddr sareal(0,m_bIPv6,m_bUdp); +#else + KviSockaddr sareal(0,false,m_bUdp); +#endif + + int size = (int)sareal.addressLength(); + + if(kvi_socket_getsockname(m_sock,sareal.socketAddress(),&size)) + { + m_uLocalPort = sareal.port(); + sareal.getStringAddress(m_szLocalIp); + } + + // and setup the READ notifier... + m_pSn = new QSocketNotifier(m_sock,QSocketNotifier::Read); + QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(incomingConnection(int))); + m_pSn->setEnabled(true); + + m_iStatus = KVI_SCRIPT_SOCKET_STATUS_LISTENING; + + c->returnValue()->setBoolean(true); + return true; +} + +void KvsObject_socket::incomingConnection(int) +{ +#ifdef COMPILE_IPV6_SUPPORT + struct sockaddr_in6 hostSockAddr6; +#endif + struct sockaddr_in hostSockAddr; + + int size = sizeof(hostSockAddr); + struct sockaddr * addr = (struct sockaddr *)&hostSockAddr; + +#ifdef COMPILE_IPV6_SUPPORT + if(m_bIPv6) + { + addr = (struct sockaddr *)&hostSockAddr6; + size = sizeof(hostSockAddr6); + } +#endif + + // Incoming connection + m_secondarySock = kvi_socket_accept(m_sock,addr,&size); + if(m_secondarySock != KVI_INVALID_SOCKET) + { + // Connected +#ifdef COMPILE_IPV6_SUPPORT + if(m_bIPv6) + { + m_uSecondaryPort = ntohs(((struct sockaddr_in6 *)addr)->sin6_port); + if(!KviNetUtils::binaryIpToStringIp_V6(((struct sockaddr_in6 *)addr)->sin6_addr,m_szSecondaryIp)) + m_szSecondaryIp = __tr("unknown"); + } else { +#endif + m_uSecondaryPort = ntohs(((struct sockaddr_in *)addr)->sin_port); + if(!KviNetUtils::binaryIpToStringIp(((struct sockaddr_in *)addr)->sin_addr,m_szSecondaryIp)) + m_szSecondaryIp = __tr("unknown"); +#ifdef COMPILE_IPV6_SUPPORT + } +#endif + KviKvsVariantList *params=0; + callFunction(this,"incomingConnectionEvent",params); + if(m_secondarySock != KVI_INVALID_SOCKET) + { + kvi_socket_close(m_secondarySock); + m_secondarySock = KVI_INVALID_SOCKET; + m_uSecondaryPort = 0; + m_szSecondaryIp=""; + } + + } // else..huh ?... wait for the next notifier call +} + +void KvsObject_socket::acceptConnection(kvi_socket_t s,kvi_u32_t uPort,const char * szIp) +{ + reset(); + m_sock = s; + m_uRemotePort = uPort; + m_szRemoteIp = szIp; +#ifdef COMPILE_IPV6_SUPPORT + KviSockaddr sareal(0,m_bIPv6,m_bUdp); +#else + KviSockaddr sareal(0,false,m_bUdp); +#endif + + int size = (int)sareal.addressLength(); + + if(kvi_socket_getsockname(m_sock,sareal.socketAddress(),&size)) + { + m_uLocalPort = sareal.port(); + sareal.getStringAddress(m_szLocalIp); + } + + m_iStatus = KVI_SCRIPT_SOCKET_STATUS_CONNECTED; + + m_pSn = new QSocketNotifier((int)m_sock,QSocketNotifier::Read); + QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(readNotifierFired(int))); + m_pSn->setEnabled(true); +} + +void KvsObject_socket::delayedConnect() +{ + if(m_pDelayTimer)delete m_pDelayTimer; + m_pDelayTimer = new QTimer(); + connect(m_pDelayTimer,SIGNAL(timeout()),this,SLOT(doConnect())); + m_pDelayTimer->setInterval(0); + m_pDelayTimer->setSingleShot(true); + m_pDelayTimer->start(); +} + +void KvsObject_socket::doConnect() +{ + qDebug("doConnect function"); + if(m_pDelayTimer)delete m_pDelayTimer; + m_pDelayTimer = 0; + + + KviSockaddr sa(m_szRemoteIp.toUtf8().data(),m_uRemotePort,!KviNetUtils::isValidStringIp(m_szRemoteIp),m_bUdp); + + if(!sa.socketAddress()) + { + unsigned int uOldConnectionId = m_uConnectionId; + QString ipAddressError=__tr2qs_ctx("Invalid IP address ","objects"); + + ipAddressError.append(m_szRemoteIp); + + KviKvsVariantList params; + QString tmp; + KviQString::sprintf(tmp,__tr2qs_ctx("Invalid IP address (%Q)","objects"),&m_szRemoteIp); + params.append(new KviKvsVariant(tmp)); + callFunction(this,"connectFailedEvent",¶ms); + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + return; + } +qDebug("Socket created"); + + // create the socket +#ifdef COMPILE_IPV6_SUPPORT + m_bIPv6 = sa.isIPv6(); + m_sock = kvi_socket_create(sa.isIPv6() ? KVI_SOCKET_PF_INET6 : KVI_SOCKET_PF_INET,m_bUdp ? KVI_SOCKET_TYPE_DGRAM : KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); +#else + m_bIPv6 = false; + m_sock = kvi_socket_create(KVI_SOCKET_PF_INET,m_bUdp ? KVI_SOCKET_TYPE_DGRAM : KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); +#endif + + if(m_sock == KVI_INVALID_SOCKET) + { + unsigned int uOldConnectionId = m_uConnectionId; + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant(__tr2qs_ctx("Failed to create the socket","objects"))); + callFunction(this,"connectFailedEvent",&lParams); + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + return; + } + qDebug("Valid socket"); + + if(!kvi_socket_setNonBlocking(m_sock)) + { + unsigned int uOldConnectionId = m_uConnectionId; + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant(__tr2qs_ctx("Failed to setup a nonblocking socket","objects"))); + callFunction(this,"connectFailedEvent",&lParams); + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + return; + } + + if(!kvi_socket_connect(m_sock,sa.socketAddress(),((int)(sa.addressLength())))) + { + int err = kvi_socket_error(); + if(!kvi_socket_recoverableConnectError(err)) + { + // Ops... + int sockError=err; + if(sockError==0) + { + // Zero error ?...let's look closer + int iSize=sizeof(int); + if(!kvi_socket_getsockopt(m_sock,SOL_SOCKET,SO_ERROR, + (void *)&sockError,&iSize))sockError=0; + } + unsigned int uOldConnectionId = m_uConnectionId; + QString callBackError=__tr2qs_ctx("Connect failure: ","objects"); + + callBackError.append((KviError::getDescription(KviError::translateSystemError(sockError)).toUtf8().data())); + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant(callBackError)); + callFunction(this,"connectFailedEvent",&lParams); + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + return; + } + } + qDebug("Socket connected"); + m_pDelayTimer = new QTimer(); + connect(m_pDelayTimer,SIGNAL(timeout()),this,SLOT(connectTimeoutSlot())); + m_pDelayTimer->setInterval(m_uConnectTimeout); + m_pDelayTimer->setSingleShot(true); + m_pDelayTimer->start(); + + m_pSn = new QSocketNotifier((int)m_sock,QSocketNotifier::Write); + QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(writeNotifierFired(int))); + m_pSn->setEnabled(true); +} + +void KvsObject_socket::connectTimeoutSlot() +{ + unsigned int uOldConnectionId = m_uConnectionId; + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant(__tr2qs_ctx("Connect attempt timed out","objects"))); + callFunction(this,"connectFailedEvent",&lParams); + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! +} + +void KvsObject_socket::delayedLookupRemoteIp() +{ + if(m_pDelayTimer)delete m_pDelayTimer; + m_pDelayTimer = new QTimer(); + connect(m_pDelayTimer,SIGNAL(timeout()),this,SLOT(lookupRemoteIp())); + + m_pDelayTimer->setInterval(0); + m_pDelayTimer->setSingleShot(true); + m_pDelayTimer->start(); +} + +void KvsObject_socket::lookupRemoteIp() +{ + qDebug("Resolve dns"); + if(m_pDelayTimer)delete m_pDelayTimer; + m_pDelayTimer = 0; + if(m_pDns)delete m_pDns; + m_pDns = new KviDnsResolver(); + connect(m_pDns,SIGNAL(lookupDone(KviDnsResolver *)),this,SLOT(lookupDone(KviDnsResolver *))); + if(!m_pDns->lookup(m_szRemoteIp,KviDnsResolver::Any)) + { + unsigned int uOldConnectionId = m_uConnectionId; + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant(__tr2qs_ctx("Can't start the DNS thread","objects"))); + callFunction(this,"connectFailedEvent",&lParams); + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + } +} + +void KvsObject_socket::lookupDone(KviDnsResolver *pDns) +{ + + if(pDns->state() != KviDnsResolver::Success) + { + unsigned int uOldConnectionId = m_uConnectionId; + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant(KviError::getDescription(pDns->error()))); + callFunction(this,"connectFailedEvent",&lParams); + + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + return; + } + m_szRemoteIp = pDns->firstIpAddress(); + qDebug("Dns resolved in %s",m_szRemoteIp.toUtf8().data()); + + delete m_pDns; + m_pDns = 0; + doConnect(); +} + +void KvsObject_socket::writeNotifierFired(int) +{ + if(m_pSn) + { + delete m_pSn; + m_pSn = 0; + } + if(m_pDelayTimer) + { + delete m_pDelayTimer; + m_pDelayTimer = 0; + } + + // Check for errors... + int sockError; + int iSize=sizeof(int); + if(!kvi_socket_getsockopt(m_sock,SOL_SOCKET,SO_ERROR,(void *)&sockError,&iSize))sockError = -1; + //sockError = 0; + if(sockError != 0) + { + //qDebug("Failed here %d",sockError); + //failed + KviError::Code eError; + if(sockError > 0) + eError = KviError::translateSystemError(sockError); + else + eError = KviError::UnknownError; //Error 0 ? + unsigned int uOldConnectionId = m_uConnectionId; + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant(KviError::getDescription(eError))); + callFunction(this,"connectFailedEvent",&lParams); + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + } else { + // Succesfully connected + // create the correct read notifier now... + m_pSn = new QSocketNotifier((int)m_sock,QSocketNotifier::Read); + QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(readNotifierFired(int))); + m_pSn->setEnabled(true); + +#ifdef COMPILE_IPV6_SUPPORT + KviSockaddr sareal(0,m_bIPv6,m_bUdp); +#else + KviSockaddr sareal(0,false,m_bUdp); +#endif + int size = (int)sareal.addressLength(); + if(kvi_socket_getsockname(m_sock,sareal.socketAddress(),&size)) + { + m_uLocalPort = sareal.port(); + sareal.getStringAddress(m_szLocalIp); + } + unsigned int uOldConnectionId = m_uConnectionId; + KviKvsVariantList *params=0; + callFunction(this,"connectEvent",params); + if(m_uConnectionId == uOldConnectionId) + m_iStatus = KVI_SCRIPT_SOCKET_STATUS_CONNECTED; + // else the connection has been already changed! + } +} + +void KvsObject_socket::readNotifierFired(int) +{ + //read da + if((m_uInBufferLen - m_uInDataLen) < KVI_READ_CHUNK) + { + m_uInBufferLen += KVI_IN_BUFFER_ALLOC_CHUNK; + //m_pInBuffer->resize(m_uInBufferLen); + m_pInBuffer = (char *)KviMemory::reallocate(m_pInBuffer,m_uInBufferLen); + } + + //int readLength = kvi_socket_recv(m_sock,m_pInBuffer->data() + m_uInDataLen,KVI_READ_CHUNK); + int readLength = kvi_socket_recv(m_sock,m_pInBuffer + m_uInDataLen,KVI_READ_CHUNK); + + if(readLength <= 0) + { + if(readLength==0) + { + unsigned int uOldConnectionId = m_uConnectionId; + KviKvsVariantList *params=0; + callFunction(this,"disconnectEvent",params); + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + return; + } else { + //check for transmission errors + int err = kvi_socket_error(); +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + if((err != EAGAIN) && (err != EINTR) && (err != WSAEWOULDBLOCK)) +#else + if((err != EAGAIN) && (err != EINTR)) +#endif + { + unsigned int uOldConnectionId = m_uConnectionId; + if(err > 0) + { + // QString error=KviError::translateSystemError(err); + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant((kvs_int_t)KviError::translateSystemError(err))); + callFunction(this,"disconnectEvent",&lParams); + } else { + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant(KviError::getDescription(KviError::RemoteEndClosedConnection))); + callFunction(this,"disconnectEvent",&lParams); + + } + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + return; + } //else transient error...wait again... + } + return; // can do nothing + } + // readLength > 0 + m_uInDataLen += readLength; + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant((kvs_int_t)readLength)); + callFunction(this,"dataAvailableEvent",&lParams); + unsigned int uOldConnectionId = m_uConnectionId; + if(m_uConnectionId == uOldConnectionId) + { + if(m_uInDataLen > (4096 * 1024)) // too much data in buffer (not reading) + { + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant(new KviKvsVariant(__tr2qs_ctx("Too much unprocessed incoming data (you've left this socket unmanaged ?)","objects")))); + callFunction(this,"disconnectEvent",&lParams); + reset(); + } + } +} + +void KvsObject_socket::eatInData(unsigned int uLen) +{ + if(uLen > m_uInDataLen)uLen = m_uInDataLen; + + m_uInDataLen -= uLen; + + if(m_uInDataLen > 0) + { + KviMemory::move(m_pInBuffer,m_pInBuffer + uLen,m_uInDataLen); + } + + unsigned int uSpace = m_uInBufferLen - m_uInDataLen; + + if(uSpace > KVI_IN_BUFFER_ALLOC_CHUNK) + { + m_uInBufferLen -= KVI_IN_BUFFER_ALLOC_CHUNK; + m_pInBuffer = (char *)KviMemory::reallocate(m_pInBuffer,m_uInBufferLen); + } +} + +void KvsObject_socket::delayedFlush(unsigned int uTimeout) +{ + if(m_pFlushTimer->isActive())m_pFlushTimer->stop(); + m_pFlushTimer->start(uTimeout); +} + +void KvsObject_socket::tryFlush() +{ + if(m_pFlushTimer->isActive())m_pFlushTimer->stop(); + + if(m_pOutBuffer->size() == 0) + { + return; + } + + int result = kvi_socket_send(m_sock,m_pOutBuffer->data(),m_pOutBuffer->size()); + + if(result >= 0) + { + if(result == m_pOutBuffer->size()) + { + m_pOutBuffer->clear(); + } else { + if(result > 0)m_pOutBuffer->remove(result); + delayedFlush(500); + } + } else { + // Oops...error ? + int err = kvi_socket_error(); +#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) + if((err == EAGAIN) || (err == EINTR) || (err = WSAEWOULDBLOCK)) +#else + if((err == EAGAIN)||(err == EINTR)) +#endif + { + // Transient error...partial send as before... + // Async continue... + delayedFlush(500); + return; + } else { + // Disconnected... :( + unsigned int uOldConnectionId = m_uConnectionId; + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant(KviError::getDescription(KviError::translateSystemError(err)))); + callFunction(this,"disconnectEvent",&lParams); + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + return; + } + } +} +void KvsObject_socket::reset() +{ + m_uConnectionId++; // this is the only place where this is incremented! + if(m_pDelayTimer) + { + delete m_pDelayTimer; + m_pDelayTimer = 0; + } + if(m_pDns) + { + delete m_pDns; + m_pDns = 0; + } + if(m_pSn) + { + delete m_pSn; + m_pSn = 0; + } + if(m_sock != KVI_INVALID_SOCKET) + { + kvi_socket_close(m_sock); + m_sock = KVI_INVALID_SOCKET; + } + if(m_pInBuffer) + { + KviMemory::free(m_pInBuffer); + m_pInBuffer = 0; + } + if(m_secondarySock) + { + kvi_socket_close(m_secondarySock); + m_secondarySock = KVI_INVALID_SOCKET; + } + m_uSecondaryPort = 0; + m_szSecondaryIp=""; + delete m_pOutBuffer; + if(m_pFlushTimer->isActive())m_pFlushTimer->stop(); + m_pOutBuffer = new KviDataBuffer(); + m_uInBufferLen = 0; + m_uInDataLen = 0; + m_iStatus = KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED; + m_uRemotePort = 0; + m_szRemoteIp=""; + m_uLocalPort = 0; + m_szLocalIp=""; + m_bIPv6 = false; +} + + + +//-------------- + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_socket.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES + + + + diff --git a/src/modules/objects/KvsObject_socket.h b/src/modules/objects/KvsObject_socket.h new file mode 100644 index 000000000..4b5704620 --- /dev/null +++ b/src/modules/objects/KvsObject_socket.h @@ -0,0 +1,113 @@ +#ifndef _CLASS_SOCKET_H_ +#define _CLASS_SOCKET_H_ +//============================================================================= +// +// File : KvsObject_socket.h +// Creation date : Sun Nov 11 03:13:46 2001 GMT by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_socket.h" +#include "KviPointerList.h" + +#include +#include + +#define KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED 0 +#define KVI_SCRIPT_SOCKET_STATUS_DNS 1 +#define KVI_SCRIPT_SOCKET_STATUS_CONNECTING 2 +#define KVI_SCRIPT_SOCKET_STATUS_LISTENING 3 +#define KVI_SCRIPT_SOCKET_STATUS_CONNECTED 4 + +class KviDnsResolver; +class KviDataBuffer; +#include "object_macros.h" + + +class KvsObject_socket : public KviKvsObject +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_socket) +protected: + bool m_bUdp; + kvi_socket_t m_sock; + int m_iStatus; + QString m_szRemoteIp; +// unsigned short int m_uRemotePort; + QString m_szLocalIp; + kvi_u32_t m_uLocalPort; + unsigned int m_uConnectTimeout; + QSocketNotifier * m_pSn; + KviDnsResolver * m_pDns; + QTimer * m_pDelayTimer; + char * m_pInBuffer; + unsigned int m_uInBufferLen; + unsigned int m_uInDataLen; + bool m_bIPv6; + unsigned int m_uConnectionId; + kvs_uint_t m_uRemotePort; + KviDataBuffer * m_pOutBuffer; + QTimer * m_pFlushTimer; + + kvi_socket_t m_secondarySock; + kvi_u32_t m_uSecondaryPort; + QString m_szSecondaryIp; +protected: + bool status(KviKvsObjectFunctionCall *c); + bool remotePort(KviKvsObjectFunctionCall *c); + bool remoteIp(KviKvsObjectFunctionCall *c); + bool localPort(KviKvsObjectFunctionCall *c); + bool localIp(KviKvsObjectFunctionCall *c); + bool functionConnect(KviKvsObjectFunctionCall *c); + bool setConnectTimeout(KviKvsObjectFunctionCall *c); + bool connectTimeout(KviKvsObjectFunctionCall *c); + + bool close(KviKvsObjectFunctionCall *c); + bool read(KviKvsObjectFunctionCall *c); + bool write(KviKvsObjectFunctionCall *c); + + + bool setProtocol(KviKvsObjectFunctionCall *c); + + bool listen(KviKvsObjectFunctionCall *c); + bool accept(KviKvsObjectFunctionCall *c); + + void delayedConnect(); + void delayedLookupRemoteIp(); + void delayedFlush(unsigned int uTimeout); + + void eatInData(unsigned int uLen); + unsigned int readGetLength(KviKvsObjectFunctionCall * params); + + void acceptConnection(kvi_socket_t s,kvi_u32_t uPort,const char * szIp); + + void reset(); +protected slots: + void doConnect(); + void lookupRemoteIp(); + void lookupDone(KviDnsResolver * pDns); + void connectTimeoutSlot(); + void writeNotifierFired(int); + void readNotifierFired(int); + void tryFlush(); + void incomingConnection(int); +}; +#endif //_CLASS_SOCKET_H_ diff --git a/src/modules/objects/KvsObject_spinBox.cpp b/src/modules/objects/KvsObject_spinBox.cpp new file mode 100644 index 000000000..080cddc0e --- /dev/null +++ b/src/modules/objects/KvsObject_spinBox.cpp @@ -0,0 +1,267 @@ +//============================================================================= +// +// File : KvsObject_spinBox.cpp +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_spinBox.h" +#include "KviError.h" +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KviIconManager.h" + +#include +/* + @doc: spinbox + @keyterms: + spinbox object class, + @title: + spinbox class + @type: + class + @short: + Provides a simple spin button. + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + This widget allows the user to choose a value either by clicking the up/down buttons + to increase/decrease the value currently displayed or by typing the value directly into the spin box. + @functions: + !fn: $setValue() + Sets the value of the spin box.[br] + See also [classfnc]$value[/classfnc]() + !fn: $setMinValue() + Sets the minimum value of the spin box. + See also [classfnc]$MinValue[/classfnc]() + !fn: $setMaxValue() + Sets the maximum value of the spin box.[br] + See also [classfnc]$maxValue[/classfnc]() + !fn: $setLineStep() + Sets the line step: when the user uses the arrows to change the spin box's value the value will be + incremented/decremented by the amount of the line step. + See also [classfnc]$lineStep[/classfnc]() + !fn: $setSpecialValueText() + Sets the special-value text. + If set, the spin box will display this text instead of a numeric value whenever the current value is equal to [classfnc]$minValue[/classfnc](). + See also [classfnc]$setSpecialValueText[/classfnc]() + !fn: $setPrefix() + This property holds the spin box's prefix.[br] + The prefix is prepended to the start of the displayed value.[br] + Typical use is to display a unit of measurement or a currency symbol. + See also [classfnc]$setSuffix[/classfnc]() + !fn: $setSuffix(); + This property holds the suffix of the spin box.[br] + The suffix is appended to the end of the displayed value.[br] + See also [classfnc]$setPrefix[/classfnc]() + !fn: $value() + Returns the value of the spin box. + See also [classfnc]$setValue[/classfnc]() + !fn: $minValue + Returns the minimum value of the spin box. + See also [classfnc]$setMinValue[/classfnc]() + !fn: $maxValue + Returns the maximum value of the spin box. + See also [classfnc]$setMaxValue[/classfnc]() + !fn: $lineStep() + Return the linestep. + !fn: $specialValueText() + Returns the special-value text. + See also [classfnc]$setSpecialValueText[/classfnc]() + !fn: $valueChangedEvent() + This function is called by the framework when the spinbox value is changed and return the new slider value as its argument.[br] + The default implementation emits the [classfnc]$valueChanged[/classfnc]() signal, + so it is easy to handle the values from many spinboxes without reimplementing + the [classfnc]$valueChangedEvent[/classfnc]() for every one.[br] + Note: If you reimplement this function to catch the spinbox value, you will have to emit the signal by yourself (if you still need it, obviously). + @signals: + !sg: $valueChanged() + This signal is emitted by the default implementation of [classfnc]valueChangedEvent[/classfnc]().[br] + If you reimplement that function you will have to emit the signal manually (if you still need it). +*/ + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_spinBox,"spinbox","widget") + + + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_spinBox,setValue); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_spinBox,setMinValue); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_spinBox,setMaxValue); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_spinBox,setLineStep); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_spinBox,setSpecialValueText); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_spinBox,value); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_spinBox,minValue); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_spinBox,maxValue); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_spinBox,lineStep); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_spinBox,specialValueText); + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_spinBox,setPrefix); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_spinBox,setSuffix); + + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_spinBox,valueChangedEvent); +KVSO_END_REGISTERCLASS(KvsObject_spinBox) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_spinBox,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_spinBox) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_spinBox) + +KVSO_END_CONSTRUCTOR(KvsObject_spinBox) + +bool KvsObject_spinBox::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + SET_OBJECT(QSpinBox) + connect(widget(),SIGNAL(valueChanged(int)),this,SLOT(valueChanged(int))); + return true; +} + + + +KVSO_CLASS_FUNCTION(spinBox,setValue) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iValue; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("value",KVS_PT_INT,0,iValue) + KVSO_PARAMETERS_END(c) + ((QSpinBox *)widget())->setValue(iValue); + return true; +} +KVSO_CLASS_FUNCTION(spinBox,setMinValue) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iMinvalue; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("min_value",KVS_PT_INT,0,iMinvalue) + KVSO_PARAMETERS_END(c) + ((QSpinBox *)widget())->setMinimum(iMinvalue); + return true; +} +KVSO_CLASS_FUNCTION(spinBox,setMaxValue) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iMaxvalue; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("max_value",KVS_PT_INT,0,iMaxvalue) + KVSO_PARAMETERS_END(c) + ((QSpinBox *)widget())->setMaximum(iMaxvalue); + return true; +} + +KVSO_CLASS_FUNCTION(spinBox,setLineStep) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iLinestep; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("line_step",KVS_PT_INT,0,iLinestep) + KVSO_PARAMETERS_END(c) + ((QSpinBox *)widget())->setSingleStep(iLinestep); + return true; +} + + +KVSO_CLASS_FUNCTION(spinBox,value) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QSpinBox *)widget())->value()); + return true; +} + +KVSO_CLASS_FUNCTION(spinBox,minValue) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QSpinBox *)widget())->minimum()); + return true; +} +KVSO_CLASS_FUNCTION(spinBox,maxValue) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QSpinBox *)widget())->maximum()); + return true; +} +KVSO_CLASS_FUNCTION(spinBox,lineStep) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QSpinBox *)widget())->singleStep()); + return true; +} + + +KVSO_CLASS_FUNCTION(spinBox,specialValueText) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setString(((QSpinBox *)widget())->specialValueText()); + return true; +} + + +KVSO_CLASS_FUNCTION(spinBox,setSpecialValueText) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETERS_END(c) + ((QSpinBox *)widget())->setSpecialValueText(szText); + return true; +} +KVSO_CLASS_FUNCTION(spinBox,setPrefix) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szPrefix; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szPrefix) + KVSO_PARAMETERS_END(c) + ((QSpinBox *)widget())->setPrefix(szPrefix); + return true; +} +KVSO_CLASS_FUNCTION(spinBox,setSuffix) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szSuffix; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szSuffix) + KVSO_PARAMETERS_END(c) + ((QSpinBox *)widget())->setSuffix(szSuffix); + return true; +} + +KVSO_CLASS_FUNCTION(spinBox,valueChangedEvent) +{ + emitSignal("valueChanged",c,c->params()); + return true; +} + +void KvsObject_spinBox::valueChanged(int value) +{ + KviKvsVariantList params(new KviKvsVariant((kvs_int_t)value)); + callFunction(this,"valueChangedEvent",¶ms); +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_spinBox.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES + diff --git a/src/modules/objects/KvsObject_spinBox.h b/src/modules/objects/KvsObject_spinBox.h new file mode 100644 index 000000000..c85b4e295 --- /dev/null +++ b/src/modules/objects/KvsObject_spinBox.h @@ -0,0 +1,64 @@ +#ifndef _CLASS_SPINBOX_H_ +#define _CLASS_SPINBOX_H_ +//============================================================================= +// +// File : KvsObject_spinBox.h +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + + +#include "KvsObject_widget.h" +#include "object_macros.h" + +class KvsObject_spinBox : public KvsObject_widget +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_spinBox) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool setTracking(KviKvsObjectFunctionCall *c); + + bool setValue(KviKvsObjectFunctionCall *c); + bool setMinValue(KviKvsObjectFunctionCall *c); + bool setMaxValue(KviKvsObjectFunctionCall *c); + bool setLineStep(KviKvsObjectFunctionCall *c); + bool setPrefix(KviKvsObjectFunctionCall *c); + bool setSuffix(KviKvsObjectFunctionCall *c); + bool value(KviKvsObjectFunctionCall *c); + bool minValue(KviKvsObjectFunctionCall *c); + bool maxValue(KviKvsObjectFunctionCall *c); + bool lineStep(KviKvsObjectFunctionCall *c); + bool setSpecialValueText(KviKvsObjectFunctionCall *c); + bool specialValueText(KviKvsObjectFunctionCall *c); + + bool valueChangedEvent(KviKvsObjectFunctionCall *c); + +protected slots: + void valueChanged(int); +}; + +#endif //!_CLASS_SPINBOX_H_ diff --git a/src/modules/objects/KvsObject_sql.cpp b/src/modules/objects/KvsObject_sql.cpp new file mode 100644 index 000000000..2c7b32438 --- /dev/null +++ b/src/modules/objects/KvsObject_sql.cpp @@ -0,0 +1,603 @@ +//============================================================================= +// +// File : KvsObject_sql.cpp +// Creation date : Wed Gen 28 2009 21:07:55 by Alessandro Carbone +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================ + +#include "kvi_debug.h" +#include "KviMemory.h" +#include "KviLocale.h" +#include "KvsObject_sql.h" +#include +#include "KvsObject_memoryBuffer.h" +#include +#include + +static KviPointerList sql_instances; + +static bool checkDuplicatedConnection(QString &szConnectionName) +{ + if(!sql_instances.count()) return false; + bool bFound=false; + for(KvsObject_sql *i = sql_instances.first(); i; i = sql_instances.next()) + { + QSqlQuery *q=i->getQueryConnectionsDict().value(szConnectionName); + if (q) + { + i->closeQueryConnection(q); + bFound=true; + break; + } + } + return bFound; +} +static void KviKvsSqlInstanceRegister(KvsObject_sql *instance) +{ + sql_instances.setAutoDelete(false); + sql_instances.append(instance); +} +static void KviKvsSqlInstanceUnregister(KvsObject_sql *instance) +{ + int idx=sql_instances.findRef(instance); + sql_instances.remove(idx); +} + +#define CHECK_QUERY_IS_INIT if (!m_pCurrentSQlQuery)\ + {\ + c->error("No query has been initialized!");\ + return false;} + + +/* + @doc: sql + @keyterms: + Sql database. + @title: + sql class + @type: + class + @short: + A sql database interface. + @inherits: + [class]object[/class] + @description: + This class permits KVIrc to have an interface with a SQL database supported by Qt library drivers. + @functions: + !fn: $setConnection(,,[,,,]) + Connects to the DBMS using the connection and selecting the database .[br] + If the optional parameter is passed, it will be used the corresponding driver (if present), otherwise Sqlite will be used. + Returns true if the operation is successful, false otherwise. + !fn:: $connectionNames([:'s']) + Returns as array or, if the flag 's' is passed, as a comma separate string all the database active connection's names. + !fn: $tablesList() + Returns as array the database tables list. + !fn: $queryInit() + Initialize the query for the database which has to be already connected. + !fn: $transaction() + Begin a transaction. + !fn: $commit() + Commit the transaction. + !fn: $setCurrentQuery() + Sets the query for the database connection , which has to be already connected, as current query. + !fn: $currentQuery() + Returns the name of the database connection for the current query, or an empty string if there aren't any initialized queries. + !fn: $closeConnection() + Closes the connection . + !fn: $queryResultsSize() + Returns the query size in rows or -1 if the query is empty or the database driver doesn' support the function. + !fn: $lastError() + Returns last error occurred. Use the more_details flag for more info about the error. + !fn: $queryExec([]) + Execs the current query . The string must follow the right syntax against the database in use. + If there are no parameters, it will exec the query previously done. + After the execution, the query will positioned on the first resulting record. + Returns true if the operation is successful, false otherwise. + See also [classfnc]$queryPrepare[/classfnc]() + !fn: $queryPrepare() + Prepare the query to execute. The string must follow the right syntax against the database in use. + It's possible to use the placeholders. It's supported either the identifier ':' and '?' but it's not possible to use them together. + Returns true if the operation is successful, false otherwise. + See also [classfnc]$queryExec[/classfnc]and[classfnc]$queryBindValue[/classfnc. + !fn: $queryBindValue() + Sets the placeholder to be bound to the value in the prepared statement. + Note that the placeholder mark (e.g :) must be included when specifing the placeholder name. + !fn: $queryPrevious() + Sets the current query position to the previous resulting record. + Returns true if the operation is successful, false otherwise. + !fn: $queryNext() + Sets the current query position to the next resulting record. + Returns true if the operation is successful, false otherwise. + !fn: $queryLast() + Sets the current query position to the last resulting record. + Returns true if the operation is successful, false otherwise. + !fn: $queryFirst() + Sets the current query position to the first resulting record. + Returns true if the operation is successful, false otherwise. + !fn: $queryRecord() + Returns a hash containing the current query's record fields. + !fn: $queryFinish() + Sets the current query to inactive. +*/ + + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_sql,"sql","object") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryLastInsertId) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,commit) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,beginTransaction) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,setConnection) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,connectionNames) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,setCurrentQuery) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,tablesList) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,currentQuery) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,closeConnection) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryInit) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryFinish) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryResultsSize) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryExec) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryPrepare) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryBindValue) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryPrevious) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryNext) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryLast) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryFirst) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryRecord) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,lastError) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,features) +KVSO_END_REGISTERCLASS(KvsObject_sql) + + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_sql,KviKvsObject) +m_pCurrentSQlQuery=0; +KviKvsSqlInstanceRegister(this); +KVSO_END_CONSTRUCTOR(KvsObject_sql) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_sql) +QHashIterator t(queryConnectionsDict); +while (t.hasNext()) +{ + t.next(); + QString szConnectionName=t.key(); + queryConnectionsDict.value(szConnectionName)->finish(); + delete queryConnectionsDict.value(szConnectionName); + QSqlDatabase::removeDatabase(szConnectionName); +} +KviKvsSqlInstanceUnregister(this); +queryConnectionsDict.clear(); + +KVSO_END_DESTRUCTOR(KvsObject_sql) + +KVSO_CLASS_FUNCTION(sql,setConnection) +{ + QString szConnectionName,szDbName,szDbDriver,szUserName,szHostName,szPassword; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("connection_name",KVS_PT_STRING,0,szConnectionName) + KVSO_PARAMETER("database_name",KVS_PT_STRING,0,szDbName) + KVSO_PARAMETER("user_name",KVS_PT_STRING,KVS_PF_OPTIONAL,szUserName) + KVSO_PARAMETER("host_name",KVS_PT_STRING,KVS_PF_OPTIONAL,szHostName) + KVSO_PARAMETER("password",KVS_PT_STRING,KVS_PF_OPTIONAL,szPassword) + KVSO_PARAMETER("database_type",KVS_PT_STRING,KVS_PF_OPTIONAL,szDbDriver) + KVSO_PARAMETERS_END(c) + if(!szDbDriver.isEmpty()) + { + QStringList drivers = QSqlDatabase::drivers(); + if (!drivers.contains(szDbDriver)) + { + c->error(__tr2qs_ctx("Missing Qt plugin for database %Q","objects"),&szDbDriver); + return false; + } + } + else szDbDriver="QSQLITE"; + if (checkDuplicatedConnection(szConnectionName)) + { + c->warning(__tr2qs_ctx("Duplicate connection name '%Q', old query connection removed","objects"),&szConnectionName); + } + QSqlDatabase db=QSqlDatabase::addDatabase(szDbDriver,szConnectionName); + db.setDatabaseName(szDbName); + db.setHostName(szHostName); + db.setUserName(szUserName); + db.setPassword(szPassword); + + c->returnValue()->setBoolean(db.open()); + return true; +} + +KVSO_CLASS_FUNCTION(sql,connectionNames) +{ + + QString szFlag; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("stringreturnflag",KVS_PT_STRING,KVS_PF_OPTIONAL,szFlag) + KVSO_PARAMETERS_END(c) + QStringList szConnectionsList=QSqlDatabase::connectionNames(); + if(szFlag.indexOf('s',0,Qt::CaseInsensitive) != -1) + { + QString szConnections=szConnectionsList.join(","); + c->returnValue()->setString(szConnections); + } + else + { + KviKvsArray *pArray=new KviKvsArray(); + for(int i=0;iset(i,new KviKvsVariant(szConnectionsList.at(i))); + } + c->returnValue()->setArray(pArray); + } + return true; +} + +KVSO_CLASS_FUNCTION(sql,queryLastInsertId) +{ + CHECK_QUERY_IS_INIT + QVariant value=m_pCurrentSQlQuery->lastInsertId(); + if (value.type()==QVariant::LongLong){ + c->returnValue()->setInteger((kvs_int_t) value.toLongLong()); + } + return true; + } +KVSO_CLASS_FUNCTION(sql,features) +{ + QString szConnectionName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("connectionName",KVS_PT_STRING,0,szConnectionName) + KVSO_PARAMETERS_END(c) + + QStringList connections = QSqlDatabase::connectionNames(); + if (!connections.contains(szConnectionName)) + { + c->warning(__tr2qs_ctx("Connection %Q does not exists","objects"),&szConnectionName); + return true; + } + QSqlDatabase db=QSqlDatabase::database(szConnectionName); + QSqlDriver *sqlDriver=db.driver(); + QStringList features; + if (sqlDriver->hasFeature(QSqlDriver::Transactions)) features.append("transactions"); + if (sqlDriver->hasFeature(QSqlDriver::QuerySize)) features.append("querysize"); + if (sqlDriver->hasFeature(QSqlDriver::BLOB)) features.append("blob"); + if (sqlDriver->hasFeature(QSqlDriver::PreparedQueries)) features.append("preparedqueries"); + if (sqlDriver->hasFeature(QSqlDriver::NamedPlaceholders)) features.append("namedplaceholders"); + if (sqlDriver->hasFeature(QSqlDriver::PositionalPlaceholders)) features.append("positionaplaceholders"); + if (sqlDriver->hasFeature(QSqlDriver::LastInsertId)) features.append("lastinsertid"); + if (sqlDriver->hasFeature(QSqlDriver::BatchOperations)) features.append("batchoperations"); + if (sqlDriver->hasFeature(QSqlDriver::SimpleLocking)) features.append("simplelocking"); + if (sqlDriver->hasFeature(QSqlDriver::LowPrecisionNumbers)) features.append("lowprecisionnumbers"); + if (sqlDriver->hasFeature(QSqlDriver::EventNotifications)) features.append("eventnotifications"); + if (sqlDriver->hasFeature(QSqlDriver::FinishQuery)) features.append("finishquery"); + if (sqlDriver->hasFeature(QSqlDriver::MultipleResultSets)) features.append("multipleresults"); + c->returnValue()->setString(features.join(",")); + return true; +} + +KVSO_CLASS_FUNCTION(sql,beginTransaction) +{ + QString szConnectionName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("connectionName",KVS_PT_STRING,0,szConnectionName) + KVSO_PARAMETERS_END(c) + + QStringList connections = QSqlDatabase::connectionNames(); + if (!connections.contains(szConnectionName)) + { + c->warning(__tr2qs_ctx("Connection %Q does not exists","objects"),&szConnectionName); + return true; + } + QSqlDatabase db=QSqlDatabase::database(szConnectionName); + db.transaction(); + return true; +} +KVSO_CLASS_FUNCTION(sql,commit) +{ + QString szConnectionName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("connectionName",KVS_PT_STRING,0,szConnectionName) + KVSO_PARAMETERS_END(c) + + QStringList connections = QSqlDatabase::connectionNames(); + if (!connections.contains(szConnectionName)) + { + c->warning(__tr2qs_ctx("Connection %Q does not exists","objects"),&szConnectionName); + return true; + } + QSqlDatabase db=QSqlDatabase::database(szConnectionName); + db.commit(); + return true; +} +KVSO_CLASS_FUNCTION(sql,closeConnection) +{ + QString szConnectionName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("connectionName",KVS_PT_STRING,0,szConnectionName) + KVSO_PARAMETERS_END(c) + + QStringList connections = QSqlDatabase::connectionNames(); + if (!connections.contains(szConnectionName)) + { + c->warning(__tr2qs_ctx("Connection %Q does not exists","objects"),&szConnectionName); + return true; + } + QSqlQuery *q=queryConnectionsDict.value(szConnectionName); + if (q) closeQueryConnection(q); + QSqlDatabase::removeDatabase(szConnectionName); + return true; +} +KVSO_CLASS_FUNCTION(sql,tablesList) +{ + QString szConnectionName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("connectionName",KVS_PT_STRING,0,szConnectionName) + KVSO_PARAMETERS_END(c) + QStringList connections = QSqlDatabase::connectionNames(); + if (!connections.contains(szConnectionName)) + { + c->warning(__tr2qs_ctx("Connection %Q does not exists","objects"),&szConnectionName); + return true; + } + QSqlDatabase db=QSqlDatabase::database(szConnectionName); + QStringList tables=db.tables(); + KviKvsArray *pArray=new KviKvsArray(); + for(int i=0;iset(i,new KviKvsVariant(tables.at(i))); + } + c->returnValue()->setArray(pArray); + return true; +} +KVSO_CLASS_FUNCTION(sql,setCurrentQuery) +{ + QString szConnectionName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("connection_name",KVS_PT_STRING,0,szConnectionName) + KVSO_PARAMETERS_END(c) + QSqlQuery *q=queryConnectionsDict.value(szConnectionName); + if(!q) + { + c->warning(__tr2qs_ctx("Connection query %Q does not exists","objects"),&szConnectionName); + return true; + } + m_pCurrentSQlQuery=q; + return true; +} +KVSO_CLASS_FUNCTION(sql,queryFinish) +{ + QString szConnectionName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("connection_name",KVS_PT_STRING,KVS_PF_OPTIONAL,szConnectionName) + KVSO_PARAMETERS_END(c) + QSqlQuery *q; + if(szConnectionName.isEmpty()) + { + q=m_pCurrentSQlQuery; + if (!q) + { + c->warning(__tr2qs_ctx("No query connection is open","objects")); + return true; + } + } + else + { + q=queryConnectionsDict.value(szConnectionName); + if(!q) + { + c->warning(__tr2qs_ctx("Query for connection %Q does not exists","objects"),&szConnectionName); + return true; + } + } + q->finish(); + return true; +} +KVSO_CLASS_FUNCTION(sql,currentQuery) +{ + if (!m_pCurrentSQlQuery) c->returnValue()->setString(QString()); + else + { + QString szKey=queryConnectionsDict.key(m_pCurrentSQlQuery); + c->returnValue()->setString(szKey); + } + return true; +} +KVSO_CLASS_FUNCTION(sql,queryInit) +{ + QString szConnectionName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("connection_name",KVS_PT_STRING,0,szConnectionName) + KVSO_PARAMETERS_END(c) + if (queryConnectionsDict.value(szConnectionName)) + { + c->warning(__tr2qs_ctx("Query %Q already initialized","objects"),&szConnectionName); + return true; + } + if(!QSqlDatabase::connectionNames().contains(szConnectionName)) + { + c->error(__tr2qs_ctx("Connection %Q is not open!","objects"),&szConnectionName); + return false; + } + m_pCurrentSQlQuery=new QSqlQuery(QSqlDatabase::database(szConnectionName)); + queryConnectionsDict[szConnectionName]=m_pCurrentSQlQuery; + return true; +} + + +KVSO_CLASS_FUNCTION(sql,queryPrepare) +{ + CHECK_QUERY_IS_INIT + QString szQuery; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("query",KVS_PT_STRING,0,szQuery) + KVSO_PARAMETERS_END(c) + c->returnValue()->setBoolean(m_pCurrentSQlQuery->prepare(szQuery)); + return true; +} +KVSO_CLASS_FUNCTION(sql,queryBindValue) +{ + CHECK_QUERY_IS_INIT + QString szFieldName; + KviKvsVariant *v; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bindName",KVS_PT_STRING,0,szFieldName) + KVSO_PARAMETER("value",KVS_PT_VARIANT,0,v) + KVSO_PARAMETERS_END(c) + QString szType; + v->getTypeName(szType); + if (v->isString()|| v->isNothing()) + { + QString szText; + v->asString(szText); + m_pCurrentSQlQuery->bindValue(szFieldName,QVariant(szText)); + } + else if (v->isReal()) + { + kvs_real_t i; + v->asReal(i); + m_pCurrentSQlQuery->bindValue(szFieldName,QVariant((double)i)); + } + else if (v->isInteger()) + { + kvs_int_t i; + v->asInteger(i); + m_pCurrentSQlQuery->bindValue(szFieldName,QVariant((int)i)); + } + else if (v->isBoolean()) + { + bool b=v->asBoolean(); + m_pCurrentSQlQuery->bindValue(szFieldName,QVariant(b)); + } + else if (v->isHObject()) + { + kvs_hobject_t hOb; + v->asHObject(hOb); + KviKvsObject *pObject; + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hOb); + if (pObject->inheritsClass("memorybuffer")) + m_pCurrentSQlQuery->bindValue(szFieldName,QVariant(*((KvsObject_memoryBuffer *)pObject)->pBuffer())); + else c->warning(__tr2qs_ctx("Only memorybuffer class object is supported","objects")); + } + else + { + QString szTypeName; + v->getTypeName(szTypeName); + c->warning(__tr2qs_ctx("Type value %Q not supported","objects"),&szTypeName); + } + return true; +} + +KVSO_CLASS_FUNCTION(sql,queryExec) +{ + CHECK_QUERY_IS_INIT + QString szQuery; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("query",KVS_PT_STRING,KVS_PF_OPTIONAL,szQuery) + KVSO_PARAMETERS_END(c) + bool bOk; + if (szQuery.isEmpty()) bOk=m_pCurrentSQlQuery->exec(); + else bOk=m_pCurrentSQlQuery->exec(szQuery.toLatin1()); + c->returnValue()->setBoolean(bOk); + return true; +} +KVSO_CLASS_FUNCTION(sql,queryNext) +{ + CHECK_QUERY_IS_INIT + if (m_pCurrentSQlQuery->isActive() && m_pCurrentSQlQuery->isSelect()) c->returnValue()->setBoolean(m_pCurrentSQlQuery->next()); + else c->returnValue()->setNothing(); + return true; +} +KVSO_CLASS_FUNCTION(sql,queryPrevious) +{ + CHECK_QUERY_IS_INIT + if (m_pCurrentSQlQuery->isActive() && m_pCurrentSQlQuery->isSelect()) c->returnValue()->setBoolean(m_pCurrentSQlQuery->previous()); + else c->returnValue()->setNothing(); + return true; +} +KVSO_CLASS_FUNCTION(sql,queryResultsSize) +{ + CHECK_QUERY_IS_INIT + c->returnValue()->setInteger(m_pCurrentSQlQuery->size()); + return true; +} +KVSO_CLASS_FUNCTION(sql,queryFirst) +{ + CHECK_QUERY_IS_INIT + if (m_pCurrentSQlQuery->isActive() && m_pCurrentSQlQuery->isSelect()) c->returnValue()->setBoolean(m_pCurrentSQlQuery->first()); + return true; +} +KVSO_CLASS_FUNCTION(sql,queryLast) +{ + CHECK_QUERY_IS_INIT + if (m_pCurrentSQlQuery->isActive() && m_pCurrentSQlQuery->isSelect()) c->returnValue()->setBoolean(m_pCurrentSQlQuery->last()); + return true; +} +KVSO_CLASS_FUNCTION(sql,queryRecord) +{ + CHECK_QUERY_IS_INIT + KviKvsHash *pHash=new KviKvsHash(); + QSqlRecord record=m_pCurrentSQlQuery->record(); + for(int i=0;iobjectController()->lookupClass("memoryBuffer"); + KviKvsVariantList params(new KviKvsVariant(QString())); + KviKvsObject * pObject = pClass->allocateInstance(0,"",c->context(),¶ms); + *((KvsObject_memoryBuffer *)pObject)->pBuffer()=value.toByteArray(); + pValue=new KviKvsVariant(pObject->handle()); + } + else pValue=new KviKvsVariant(QString()); + pHash->set(record.fieldName(i),pValue); + KviKvsVariant *value2=pHash->get(record.fieldName(i)); + value2->type(); + } + c->returnValue()->setHash(pHash); + return true; +} + +KVSO_CLASS_FUNCTION(sql,lastError) +{ + CHECK_QUERY_IS_INIT + bool bMoreErrorDetails; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("more",KVS_PT_BOOLEAN,KVS_PF_OPTIONAL,bMoreErrorDetails) + KVSO_PARAMETERS_END(c) + QString szError; + QSqlError error=m_pCurrentSQlQuery->lastError(); + if (bMoreErrorDetails) szError=error.text(); + else + { + if (error.type()==QSqlError::StatementError) szError="SyntaxError"; + else if (error.type()==QSqlError::ConnectionError) szError="ConnectionError"; + else if (error.type()==QSqlError::TransactionError) szError="TransactionError"; + else szError="UnkonwnError"; + } + c->returnValue()->setString(szError); + return true; +} +void KvsObject_sql::closeQueryConnection(QSqlQuery * query) +{ + if (query==m_pCurrentSQlQuery) m_pCurrentSQlQuery=0; + query->finish(); + queryConnectionsDict.remove(queryConnectionsDict.key(query)); + delete query; + } + diff --git a/src/modules/objects/KvsObject_sql.h b/src/modules/objects/KvsObject_sql.h new file mode 100644 index 000000000..51ade479b --- /dev/null +++ b/src/modules/objects/KvsObject_sql.h @@ -0,0 +1,79 @@ +#ifndef _CLASS_SQLITE_H_ +#define _CLASS_SQLITE_H_ +//============================================================================= +// +// File : class_sqlite.h +// Creation date : Wed Gen 28 2009 21:07:55 by Alessandro Carbone +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" +#include "KviCString.h" +#include "KviPointerList.h" +#include "KviKvsVariant.h" +#include "object_macros.h" +#include +#include + +class KvsObject_sql : public KviKvsObject +{ +public: + KVSO_DECLARE_OBJECT(KvsObject_sql) +protected: + QSqlQuery *m_pCurrentSQlQuery; + QHash queryConnectionsDict; + + public: + QHash & getQueryConnectionsDict(){return queryConnectionsDict;}; + void closeQueryConnection(QSqlQuery *); + QSqlQuery & getQuery() + { + //if (currentSQlQuery) return *currentSQlQuery; + return *m_pCurrentSQlQuery; + }; + bool setConnection(KviKvsObjectFunctionCall *c); + bool connectionNames(KviKvsObjectFunctionCall *c); + bool features(KviKvsObjectFunctionCall *c); + bool queryLastInsertId(KviKvsObjectFunctionCall *c); + + bool tablesList(KviKvsObjectFunctionCall *c); + bool beginTransaction(KviKvsObjectFunctionCall *c); + bool commit(KviKvsObjectFunctionCall *c); + + bool queryResultsSize(KviKvsObjectFunctionCall *c); + bool queryNext(KviKvsObjectFunctionCall *c); + bool queryPrevious(KviKvsObjectFunctionCall *c); + bool queryFirst(KviKvsObjectFunctionCall *c); + bool queryLast(KviKvsObjectFunctionCall *c); + bool queryExec(KviKvsObjectFunctionCall *c); + bool queryRecord(KviKvsObjectFunctionCall *c); + bool queryPrepare(KviKvsObjectFunctionCall *c); + bool queryBindValue(KviKvsObjectFunctionCall *c); + bool setCurrentQuery(KviKvsObjectFunctionCall *c); + bool currentQuery(KviKvsObjectFunctionCall *c); + bool queryFinish(KviKvsObjectFunctionCall *c); + bool queryInit(KviKvsObjectFunctionCall *c); + bool closeConnection(KviKvsObjectFunctionCall *c); + bool lastError(KviKvsObjectFunctionCall *c); + +}; + + +#endif //_CLASS_SQLITE_H_ diff --git a/src/modules/objects/KvsObject_tabWidget.cpp b/src/modules/objects/KvsObject_tabWidget.cpp new file mode 100644 index 000000000..0d7cc8a34 --- /dev/null +++ b/src/modules/objects/KvsObject_tabWidget.cpp @@ -0,0 +1,456 @@ +//============================================================================= +// +// File : KvsObject_tabWidget.cpp +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_tabWidget.h" +#include "KviError.h" +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KviIconManager.h" + +#include + +/* + @doc: tabWidget + @keyterms: + tabWidget object class, + @title: + tabWidget class + @type: + class + @short: + Provides a Tab Widget. + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + The tabWidget class provides a stack of tabbed widgets.[br] + Each tab is associated with a different widget (called a `page').[br] + Only the current tab's page is shown in the page area; all the others tabs pages are hidden.[br] + The user can show a different page by clicking on its tab.[br] + @functions: + !fn: $addTab(,,[]) + Adds another page to the tab view with the text label and optional icon. + !fn: $insertTab(,,) + Inserts another tab and page to the tab view with name and label-text specified.[br] + If index is not specified, the tab is simply appended.[br] + Otherwise the new tab is inserted at the specified position. + !fn: $setTabToolTip(,) + Sets the tab tool tip for the tabWidget to . + !fn: $removeTabToolTip() + Removes the tab tool tip for the tab. If the page does not have a tip, nothing happens. + !fn: $setTabLabel(, ) + Sets the tab label for to label. + !fn: $changeTab(,,[]) + Defines a new label, and optional icon, for the tab . + !fn: $setCurrentPage() + Sets the index position of the current tab page to . + !fn: $currentPageIndex() + Returns the current page index. + !fn: $tabLabel() + Returns the tab label of the . + !fn: $widgetAt() + Returns the tab widget of the or 0 if index is out of the tabs count. + !fn: $currentTabLabel() + Returns the label of the current tab. + !fn: $removePage() + Remove the page . + !fn: $setTabPosition() + Sets TabPosition. Valid parameters are : Top, Bottom. + !fn: $count() + Returns the number of tabs in the tab bar. + !fn: $setTabsClosable() + Sets whether close buttons are automatically added to each tab + !fn: $currentChangedEvent() + This function is invoched when the current tab was changed.[br] + The default implementation emits the [classfnc]$currentChange[/classfnc]() signal. + !fn: $tabCloseRequestEvent() + This function is invoched when when the close button on a tab is clicked. + The index is the index of the tab that should be removed.[br] + The default implementation emits the [classfnc]$tabCloseRequest[/classfnc]() signal. + See also [classfnc]$setTabsClosable[/classfnc](). + @examples: + [example] + // First we'll create the main tabWidget. + %Tabwidget=$new(tabWidget) + %Tabwidget->$setToolTip("Example of TabWidget class") + %Tabwidget->$setTabPosition(Top) + %Tabwidget->$resize(300,200) + // Now we'll create the new widgets and put they in to the main tabWidget. + %firsttab=$new(vbox) + %secondtab=$new(vbox) + // Now we'll create the item to put in to tab's pages. + // First tab + %hbox=$new(hbox,%firsttab) + %labelbt=$new(label,%hbox) + %labelbt->$settext(Botton Tab) + %labeltt=$new(label,%hbox) + %labeltt->$settext(Top Tab) + %hbox=$new(hbox,%firsttab) + %buttontb=$new(button,%hbox) + %buttontb->$settext("To &Botton") + %buttontt=$new(button,%hbox) + %buttontt->$settext("To &Top") + // Now we'll give a layout to all items. + // This also allows to use privateimpl without making buttons global variables + // Add the page to the main tab. + %Tabwidget->$addTab(%firsttab,Top&Button,33) + // Implementing the action to do when the user click the buttons. + privateimpl(%buttontb,mousepressevent) + { + %Tabwidget->$setTabPosition(Bottom) + } + privateimpl(%buttontt,mousepressevent) + { + %Tabwidget->$setTabPosition(Top) + } + // We do the same work with the second tab's page. + %labelwp=$new(label,%secondtab) + %labelwp->$settext("Enjoy the new Class provided by") + %labelwp->$setalignment("Center") + %labelgen=$new(label,%secondtab) + %labelgen->$settext(Grifisx \& Noldor) + %labelgen->$setalignment("Center") + %Tabwidget->$addTab(%secondtab,&About,50) + // Let's show our example. + %Tabwidget->$show() + [/example] + @signals: + !sg: $currentChange() + This signal is emitted by the default implementation of [classfnc]$currentChangedEvent[/classfnc]().[br] + If you reimplement that function you will have to emit the signal manually (if you still need it).[br] + !sg: $tabCloseRequest() + This signal is emitted by the default implementation of [classfnc]tabCloseRequestEvent[/classfnc]().[br] +*/ + +KVSO_BEGIN_REGISTERCLASS(KvsObject_tabWidget,"tabWidget","widget") + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tabWidget,addTab) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tabWidget,insertTab) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tabWidget,setTabToolTip) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tabWidget,removeTabToolTip) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tabWidget,setTabLabel) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tabWidget,changeTab) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tabWidget,setCurrentPage) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tabWidget,currentPageIndex) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tabWidget,tabLabel) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tabWidget,currentTabLabel) + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tabWidget,count) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tabWidget,removePage) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tabWidget,widgetAt) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tabWidget,setTabPosition) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tabWidget,setTabsClosable) + + // events + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tabWidget,currentChangedEvent) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tabWidget,tabCloseRequestEvent) + + + +KVSO_END_REGISTERCLASS(KvsObject_tabWidget) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_tabWidget,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_tabWidget) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_tabWidget) +tabsList.clear();; +KVSO_END_CONSTRUCTOR(KvsObject_tabWidget) + +bool KvsObject_tabWidget::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + SET_OBJECT(QTabWidget) + connect(widget(),SIGNAL(currentChanged(int)),this,SLOT(slotCurrentChanged(int))); + connect(widget(),SIGNAL(tabCloseRequested(int)),this,SLOT(slotTabCloseRequest(int))); + + return true; +} +KVSO_CLASS_FUNCTION(tabWidget,setTabsClosable) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bClosable; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bool_flag",KVS_PT_BOOLEAN,0,bClosable) + KVSO_PARAMETERS_END(c) + ((QTabWidget *)widget())->setTabsClosable(bClosable); + return true; +} + +KVSO_CLASS_FUNCTION(tabWidget,addTab) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsObject *pObject; + QString szLabel,szIcon; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel) + KVSO_PARAMETER("icon_id",KVS_PT_STRING,KVS_PF_OPTIONAL,szIcon) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + CHECK_HOBJECT_IS_WIDGET(pObject) + QPixmap * pix = g_pIconManager->getImage(szIcon); + if(pix){ + ((QTabWidget *)widget())->addTab(((QWidget *)(pObject->object())),QIcon(*pix),szLabel); + } + else((QTabWidget *)widget())->addTab(((QWidget *)(pObject->object())),szLabel); + tabsList.append(hObject); + return true; +} +KVSO_CLASS_FUNCTION(tabWidget,widgetAt) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iIndex; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_INTEGER,0,iIndex) + KVSO_PARAMETERS_END(c) + if (iIndex>=tabsList.count()||iIndex<0) c->returnValue()->setHObject((kvs_hobject_t)0); + else c->returnValue()->setHObject(tabsList.at(iIndex)); + return true; +} + +KVSO_CLASS_FUNCTION(tabWidget,insertTab) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsObject *pObject; + QString szLabel,szIcon; + kvs_uint_t uIndex; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("tab_widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel) + KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex) + KVSO_PARAMETER("icon_id",KVS_PT_STRING,KVS_PF_OPTIONAL,szIcon) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + CHECK_HOBJECT_IS_WIDGET(pObject) + QPixmap * pix = g_pIconManager->getImage(szIcon); + if(pix){ + ((QTabWidget *)widget())->insertTab(uIndex,(QWidget *)(pObject->object()),QIcon(*pix),szLabel); + } + else ((QTabWidget *)widget())->insertTab(uIndex,((QWidget *)(pObject->object())),szLabel); + tabsList.insert(uIndex,hObject); + return true; +} + +KVSO_CLASS_FUNCTION(tabWidget,setCurrentPage) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t iIndex; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,iIndex) + KVSO_PARAMETERS_END(c) + ((QTabWidget *)widget())->setCurrentIndex(iIndex); + return true; +} +KVSO_CLASS_FUNCTION(tabWidget,setTabToolTip) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsObject *pObject; + QString szTooltip; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("tab_widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETER("tooltip",KVS_PT_STRING,0,szTooltip) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + CHECK_HOBJECT_IS_WIDGET(pObject) + int iIdx = ((QTabWidget *)widget())->indexOf (((QWidget *)(pObject->object()))); + if (iIdx == -1) + { + c->warning(__tr2qs_ctx("Can't find the tab ","objects")); + return true; + } + ((QTabWidget *)widget())->setTabToolTip(iIdx,szTooltip); + return true; +} +KVSO_CLASS_FUNCTION(tabWidget,removeTabToolTip) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsObject *pObject; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("tab_widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + CHECK_HOBJECT_IS_WIDGET(pObject) + int iIdx = ((QTabWidget *)widget())->indexOf (((QWidget *)(pObject->object()))) ; + if (iIdx==-1) + { + c->warning(__tr2qs_ctx("Can't find the tab ","objects")); + return true; + } + ((QTabWidget *)widget())->setTabToolTip(iIdx,QString()); + return true; +} + +KVSO_CLASS_FUNCTION(tabWidget,setTabLabel) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsObject *pObject; + QString szLabel; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("tab_widget",KVS_PT_HOBJECT,0, hObject) + KVSO_PARAMETER("tooltip",KVS_PT_STRING,0,szLabel) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + CHECK_HOBJECT_IS_WIDGET(pObject) + int iIdx = ((QTabWidget *)widget())->indexOf (((QWidget *)(pObject->object()))); + if (iIdx == -1) + { + c->warning(__tr2qs_ctx("Can't find the tab ","objects")); + return true; + } + ((QTabWidget *)widget())->setTabText(iIdx,szLabel); + return true; +} +KVSO_CLASS_FUNCTION(tabWidget,currentPageIndex) +{ + CHECK_INTERNAL_POINTER(widget()) + int index=((QTabWidget *)widget())->currentIndex(); + c->returnValue()->setInteger(index); + return true; +} +KVSO_CLASS_FUNCTION(tabWidget,tabLabel) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t uIndex; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_INT,0,uIndex) + KVSO_PARAMETERS_END(c) + QString label=((QTabWidget *)widget())->tabText(uIndex); + c->returnValue()->setString(label); + return true; +} + + +KVSO_CLASS_FUNCTION(tabWidget,count) +{ + CHECK_INTERNAL_POINTER(widget()) + int count = ((QTabWidget *)widget())->count(); + c->returnValue()->setInteger(count); + return true; +} + +KVSO_CLASS_FUNCTION(tabWidget,currentTabLabel) +{ + CHECK_INTERNAL_POINTER(widget()) + int i= ((QTabWidget *)widget())->currentIndex(); + QString label=((QTabWidget *)widget())->tabText(i); + c->returnValue()->setString(label); + return true; +} +KVSO_CLASS_FUNCTION(tabWidget,removePage) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsObject *pObject; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("tab_widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + CHECK_HOBJECT_IS_WIDGET(pObject) + int iIdx = ((QTabWidget *)widget())->indexOf (((QWidget *)(pObject->object()))); + if (iIdx == -1) + { + c->warning(__tr2qs_ctx("Can't find the tab ","objects")); + return true; + } + ((QTabWidget *)widget())->removeTab(iIdx); + tabsList.removeAt(iIdx); + return true; +} + +KVSO_CLASS_FUNCTION(tabWidget,changeTab) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsObject *pObject; + QString szLabel,szIcon; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("tab_widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel) + KVSO_PARAMETER("icon_id",KVS_PT_STRING,KVS_PF_OPTIONAL,szIcon) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + CHECK_HOBJECT_IS_WIDGET(pObject) + int iIdx = ((QTabWidget *)widget())->indexOf (((QWidget *)(pObject->object()))); + if (iIdx == -1) + { + c->warning(__tr2qs_ctx("Can't find the tab","objects")); + return true; + } + QPixmap * pix = g_pIconManager->getImage(szIcon); + if(pix)((QTabWidget *)widget())->setTabIcon(iIdx,QIcon(*pix)); + ((QTabWidget *)widget())->setTabText(iIdx,szLabel); + return true; +} + +KVSO_CLASS_FUNCTION(tabWidget,setTabPosition) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szPos; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("tab_position",KVS_PT_STRING,0,szPos) + KVSO_PARAMETERS_END(c) + if(KviQString::equalCI(szPos,"Top")) + ((QTabWidget *)widget())->setTabPosition(QTabWidget::North); + else if(KviQString::equalCI(szPos,"Bottom")) + ((QTabWidget *)widget())->setTabPosition(QTabWidget::South); + else c->warning( __tr2qs_ctx("Unknown position '%Q'","objects"),&szPos); + return true; +} + +KVSO_CLASS_FUNCTION(tabWidget,currentChangedEvent) +{ + + emitSignal("currentChanged",c,c->params()); + return true; +} + +void KvsObject_tabWidget::slotCurrentChanged(int value) +{ + KviKvsVariantList params(new KviKvsVariant((kvs_int_t)value)); + callFunction(this,"currentChangedEvent",¶ms); +} + +KVSO_CLASS_FUNCTION(tabWidget,tabCloseRequestEvent) +{ + + emitSignal("tabCloseRequested",c,c->params()); + return true; +} + +void KvsObject_tabWidget::slotTabCloseRequest(int iIndex) +{ + KviKvsVariantList params(new KviKvsVariant((kvs_int_t)iIndex)); + callFunction(this,"tabCloseRequestEvent",¶ms); +} +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_tabWidget.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES + diff --git a/src/modules/objects/KvsObject_tabWidget.h b/src/modules/objects/KvsObject_tabWidget.h new file mode 100644 index 000000000..72f893758 --- /dev/null +++ b/src/modules/objects/KvsObject_tabWidget.h @@ -0,0 +1,67 @@ +#ifndef _CLASS_TABWIDGET_H_ +#define _CLASS_TABWIDGET_H_ +//============================================================================= +// +// File : KvsObject_tabWidget.cpp +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_widget.h" +#include "object_macros.h" + +class KvsObject_tabWidget : public KvsObject_widget +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_tabWidget) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + QList tabsList; + + bool addTab(KviKvsObjectFunctionCall *c); + bool insertTab(KviKvsObjectFunctionCall *c); + bool setTabToolTip(KviKvsObjectFunctionCall *c); + bool removeTabToolTip(KviKvsObjectFunctionCall *c); + bool setTabLabel(KviKvsObjectFunctionCall *c); + bool setCurrentPage(KviKvsObjectFunctionCall *c); + bool currentPageIndex(KviKvsObjectFunctionCall *c); + bool tabLabel(KviKvsObjectFunctionCall *c); + bool currentTabLabel(KviKvsObjectFunctionCall *c); + bool count(KviKvsObjectFunctionCall *c); + bool changeTab(KviKvsObjectFunctionCall *c); + bool removePage(KviKvsObjectFunctionCall *c); + bool setTabPosition(KviKvsObjectFunctionCall *c); + bool setTabsClosable(KviKvsObjectFunctionCall *c); + bool widgetAt(KviKvsObjectFunctionCall *c); + + // events + bool currentChangedEvent(KviKvsObjectFunctionCall *c); + bool tabCloseRequestEvent(KviKvsObjectFunctionCall *c); + +protected slots: + void slotCurrentChanged(int); + void slotTabCloseRequest(int); +}; + +#endif //!_CLASS_TABWIDGET_H_ diff --git a/src/modules/objects/KvsObject_tableWidget.cpp b/src/modules/objects/KvsObject_tableWidget.cpp new file mode 100644 index 000000000..6bda1f64a --- /dev/null +++ b/src/modules/objects/KvsObject_tableWidget.cpp @@ -0,0 +1,796 @@ +//============================================================================= +// +// File : KvsObject_tableWidget.cpp +// Creation date : Wed 04 Feb 2009 09:30:05 CEST by Carbone Alessandro +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_tableWidget.h" +#include "KvsObject_painter.h" +#include "KvsObject_pixmap.h" + +#include "kvi_debug.h" +#include "KviApplication.h" +#include "KviLocale.h" +#include "KviError.h" +#include "KviIconManager.h" +#include "KviFile.h" +#include "KviKvsArrayCast.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const int item_flags[] = { + Qt::NoItemFlags, + Qt::ItemIsSelectable, + Qt::ItemIsEditable, + Qt::ItemIsDragEnabled, + Qt::ItemIsDropEnabled, + Qt::ItemIsUserCheckable, + Qt::ItemIsEnabled, + Qt::ItemIsTristate +}; + +const char * const itemflags_tbl[] = { + "noitemflag", + "selectable", + "editable", + "dragEnabled", + "dropEnabled", + "userCheckable", + "enabled", + "tristate" +}; + +#define itemflags_num (sizeof(itemflags_tbl) / sizeof(itemflags_tbl[0])) + +/* + @doc:tablewidget + @title: + tablewidget class + @type: + class + @short: + Tablewidget widget. + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + This widget provides a table. + @functions: + !fn: $setText(,,[]) + Sets the contents of the cell pointeid by row and col to text. + !fn: $setTooltip(,,[]) + Sets the tooltip of the cell pointeid by row and col to text. + !fn: $setNumber(,,[]). + Sets the contents of the cell pointeid by row and col to number. + !fn: $text(,) + Returns the text of the cell pointed by row and col. + !fn: $setHorizontalHeaderLabels() + Sets the horizontal header labels using labels. + !fn: $showHorizontalHeader() + Shows the horizontal header. + !fn: $hideHorizontalHeader() + Hides the horizontal header. + !fn: $setVerticalHeaderLabels() + Sets the vertical header labels using labels. + !fn: $showVerticalHeader() + Shows the vertical header. + !fn: $hideVerticalHeader() + Hides the vertical header. + !fn: $setRowCount() + Sets the number of rows in the table. + !fn: $rowCount() + Returns the number of rows in the table. + !fn: $currentRow() + Returns the current row. + Useful in the [classfnc]customContextMenuRequestedEvent[/classfnc]. + !fn: $insertRow() + Insert an empty row at . + !fn: $removeRow() + Remove the row at and all its items from the table. + !fn: $insertColumn() + Insert an empty column at . + !fn: $removeColumn() + Remove the column at and all its items from the table. + !fn: $setColumnCount() + Sets the number of columns in the table. + !fn: $columnCount() + Returns the number of columns in the table. + !fn: $currentRow() + Returns the current column. + Useful in the [classfnc]customContextMenuRequestedEvent[/classfnc] + !fn: $setFlag(,,, , ...) + Sets the flags for the cell pointed by row and col to the given flags. + These determine whether the cell can be selected or modified. + Supported flags are: + - noitemflag : no flag sets; + - selectable : cell is selecatble; + - editable : cell is editable; + - dragEnabled : cell can dragged; + - dropEnabled : cell can used as drop target; + - userCheckable : cell is checkable; + - enabled :cell is enabled; + - tristate : cell is checkable with three separate states. + !fn: $setCellWidget(,,) + Sets the given widget to be displayed in the cell in the given row and column, passing the ownership of the widget to the table. + !fn: $setIcon(,,) + Sets the cell icon pointed by ,. + Icon parameter can be a standard KVIrc [doc:image_id]image identifier[/doc] icon or a KVS pixmap's object. + !fn: $hideRow() + Hides the row . + !fn: $showRow() + Shows the row . + !fn: $hideColumn() + Hides the column
. + !fn: $showColumn() + Shows the column . + !fn: $clear() + Clears the table. + !fn: $itemEnteredEvent() + This event is triggered when the mouse cursor enters an cell. + !fn: $cellActivatedEvent() + This event is triggered when the cell specified by row and column has been activated + !fn: $cellDoubleClickedEvent() + This event is triggered whenever a cell in the table is double clicked. + !fn: $paintCellEvent(,,,,) + This event handler can be reimplemented to repaint cells. + The framework will pass the row/col coordinates, cell's width and height, and, as parameter, a [class]painter[/class]object. + You don't need to begin/end/delete the painter. + !fn: $sizeHintCellRequestEvent() + This event handler can be reimplemented to pass a custom size hint for this cell to the table layout + !fn; $resizeRowsToContents() + This function will try to redistribute the available space according to the space requirement of each row + !fn; $resizeColumnsToContents() + This function will try to redistribute the available space according to the space requirement of each column + @signals: + !sg: $clicked() + This signal is emitted by the default implementation of [classfnc]$clickEvent[/classfnc](). + +*/ + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_tableWidget,"tablewidget","widget") + + // Horizontal Header + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,setHorizontalHeaderLabels) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,hideHorizontalHeader) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,hideVerticalHeader) + + // Vertical Header + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,setVerticalHeaderLabels) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,showHorizontalHeader) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,showVerticalHeader) + + // Rows-Columns + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,setRowCount) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,insertRow) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,insertColumn) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,removeRow) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,removeColumn) + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,rowCount) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,currentRow) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,setColumnCount) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,columnCount) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,currentColumn) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,itemRowColAt) + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,hideRow) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,showRow) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,hideColumn) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,showColumn) + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,resizeRowsToContents) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,resizeColumnsToContents) + + // Item (text. icon, widget) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,setText) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,setNumber) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,setToolTip) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,text) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,setCellWidget) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,setIcon) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,clear) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_tableWidget,setItemFlags); + + KVSO_REGISTER_HANDLER(KvsObject_tableWidget,"itemEnteredEvent",itemEnteredEvent); + KVSO_REGISTER_HANDLER(KvsObject_tableWidget,"cellActivatedEvent",cellActivatedEvent); + KVSO_REGISTER_HANDLER(KvsObject_tableWidget,"cellDoubleClickedEvent",cellDoubleClickedEvent); + KVSO_REGISTER_STANDARD_TRUERETURN_HANDLER(KvsObject_tableWidget,"paintCellEvent") + KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KvsObject_tableWidget,"sizeHintCellRequestEvent") + + + +KVSO_END_REGISTERCLASS(KvsObject_tableWidget) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_tableWidget,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_tableWidget) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_tableWidget) +/*if (m_pCellItemDelegate) +{ + delete m_pCellItemDelegate; + m_pCellItemDelegate=0; +}*/ +KVSO_END_DESTRUCTOR(KvsObject_tableWidget) + +bool KvsObject_tableWidget::init(KviKvsRunTimeContext *c,KviKvsVariantList *) +{ + + SET_OBJECT(QTableWidget) + m_pCellItemDelegate=new KviCellItemDelegate(((QTableWidget *)widget()),this); + + m_pContext=c; + ((QTableWidget *)widget())->setItemDelegate(m_pCellItemDelegate); + ((QTableWidget *)widget())->verticalHeader()->resizeSections(QHeaderView::Custom ); + ((QTableWidget *)widget())->horizontalHeader()->resizeSections(QHeaderView::Custom ); + + connect(widget(),SIGNAL(itemEntered(QTableWidgetItem *)),this,SLOT(slotItemEntered(QTableWidgetItem *))); + connect(widget(),SIGNAL(cellActivated(int,int)),this,SLOT(cellActivated(int,int))); + connect(widget(),SIGNAL(cellDoubleClicked(int,int)),this,SLOT(cellDoubleClicked(int,int))); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,clear) +{ + CHECK_INTERNAL_POINTER(widget()) + ((QTableWidget *)widget())->clear(); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,resizeRowsToContents) +{ + CHECK_INTERNAL_POINTER(widget()) + //qDebug("resize row to contents"); + + ((QTableWidget *)widget())->resizeRowsToContents(); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,resizeColumnsToContents) +{ + CHECK_INTERNAL_POINTER(widget()) + //qDebug("resize coluns to contents"); + ((QTableWidget *)widget())->resizeColumnsToContents(); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,setText) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uCol,uRow; + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) + KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETERS_END(c) + if(uRow >= (uint)((QTableWidget *)widget())->rowCount() || uRow >= (uint)((QTableWidget *)widget())->rowCount()) + c->warning(__tr2qs_ctx("Item out of the tablewidget size","objects")); + QTableWidgetItem * pItem = ((QTableWidget *)widget())->item(uRow,uCol); + if(!pItem) + { + pItem = new QTableWidgetItem(); + ((QTableWidget *)widget())->setItem(uRow,uCol,pItem); + } + pItem->setText(szText); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,setNumber) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uCol,uRow; + kvs_int_t iNumber; + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) + KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETER("number",KVS_PT_INT,0,iNumber) + KVSO_PARAMETERS_END(c) + if(uRow >= (uint)((QTableWidget *)widget())->rowCount() || uRow >= (uint)((QTableWidget *)widget())->rowCount()) + c->warning(__tr2qs_ctx("Item out of the tablewidget size","objects")); + QTableWidgetItem * pItem = ((QTableWidget *)widget())->item(uRow,uCol); + if(!pItem) + { + pItem = new QTableWidgetItem(); + ((QTableWidget *)widget())->setItem(uRow,uCol,pItem); + } + pItem->setData(0,(int)iNumber); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,insertRow) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uRow; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) + KVSO_PARAMETERS_END(c) + ((QTableWidget *)widget())->insertRow(uRow); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,insertColumn) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uCol; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETERS_END(c) + ((QTableWidget *)widget())->insertColumn(uCol); + return true; +} +KVSO_CLASS_FUNCTION(tableWidget,removeRow) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uRow; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) + KVSO_PARAMETERS_END(c) + ((QTableWidget *)widget())->removeRow(uRow); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,removeColumn) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uCol; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETERS_END(c) + ((QTableWidget *)widget())->removeColumn(uCol); + return true; +} + + +KVSO_CLASS_FUNCTION(tableWidget,setIcon) +{ + kvs_uint_t uCol,uRow; + KviKvsObject *obPixmap; + kvs_hobject_t obHpixmap; + KviKvsVariant * vPixmap; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) + KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETER("icon",KVS_PT_VARIANT,0,vPixmap) + KVSO_PARAMETERS_END(c) + QPixmap * pix = 0; + if(vPixmap->isHObject()) + { + vPixmap->asHObject(obHpixmap); + obPixmap=KviKvsKernel::instance()->objectController()->lookupObject(obHpixmap); + if(!obPixmap->inheritsClass("pixmap")) + { + c->warning(__tr2qs_ctx("Pixmap object or image Id required","objects")); + return true; + } + pix=((KvsObject_pixmap *)obPixmap)->getPixmap(); + } else { + QString szPix; + vPixmap->asString(szPix); + pix=g_pIconManager->getImage(szPix); + if(!pix) + { + c->warning(__tr2qs_ctx("Error occured: the suitable file '%Q' is not of the correct format or it is not a valid icon number.","objects"),&szPix); + return true; + } + } + QTableWidgetItem * pItem = ((QTableWidget *)widget())->item(uRow,uCol); + if(!pItem) + { + pItem = new QTableWidgetItem(); + ((QTableWidget *)widget())->setItem(uRow,uCol,pItem); + } + pItem->setIcon(QIcon(*pix)); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,text) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uCol,uRow; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) + KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETERS_END(c) + QTableWidgetItem * pItem = ((QTableWidget *)widget())->item(uRow,uCol); + if(!pItem) c->returnValue()->setNothing(); + else c->returnValue()->setString(((QTableWidget *)widget())->item(uRow,uCol)->text()); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,setRowCount) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uRow; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) + KVSO_PARAMETERS_END(c) + ((QTableWidget *)widget())->setRowCount(uRow); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,rowCount) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QTableWidget *)widget())->rowCount()); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,currentRow) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QTableWidget *)widget())->currentRow()); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,currentColumn) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QTableWidget *)widget())->currentColumn()); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,columnCount) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setInteger(((QTableWidget *)widget())->columnCount()); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,itemRowColAt) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iXpos,iYpos; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("x_pos",KVS_PT_INT,0,iXpos) + KVSO_PARAMETER("y_pos",KVS_PT_INT,0,iYpos) + KVSO_PARAMETERS_END(c) + KviKvsArray *pArray; + QPoint pPoint=((QTableWidget *)widget())->viewport()->mapFromGlobal(QPoint(iXpos,iYpos)); + QTableWidgetItem *pItem=((QTableWidget *)widget())->itemAt(pPoint.x(),pPoint.y()); + pArray=new KviKvsArray; + if (!pItem) { + pArray->set(0,new KviKvsVariant((kvs_int_t)-1)); + pArray->set(1,new KviKvsVariant((kvs_int_t)-1)); + } + else { + pArray->set(0,new KviKvsVariant((kvs_int_t)pItem->row())); + pArray->set(1,new KviKvsVariant((kvs_int_t)pItem->column())); + } + c->returnValue()->setArray(pArray); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,setToolTip) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szTooltip; + kvs_uint_t uRow,uCol; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) + KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETER("tooltip",KVS_PT_STRING,0,szTooltip) + KVSO_PARAMETERS_END(c) + QTableWidgetItem *pItem=((QTableWidget *)widget())->item(uRow,uCol); + if (pItem) pItem->setToolTip(szTooltip); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,setColumnCount) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uCol; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETERS_END(c) + ((QTableWidget *)widget())->setColumnCount(uCol); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,hideColumn) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uCol; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETERS_END(c) + ((QTableWidget *)widget())->hideColumn(uCol); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,showColumn) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uCol; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETERS_END(c) + ((QTableWidget *)widget())->showColumn(uCol); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,hideRow) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uRow; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uRow) + KVSO_PARAMETERS_END(c) + ((QTableWidget *)widget())->hideRow(uRow); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,showRow) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_uint_t uRow; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uRow) + KVSO_PARAMETERS_END(c) + ((QTableWidget *)widget())->showRow(uRow); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,setHorizontalHeaderLabels) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsArrayCast ac; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("labels",KVS_PT_ARRAYCAST,0,ac) + KVSO_PARAMETERS_END(c) + QStringList szColumns; + if(KviKvsArray * a = ac.array()) + { + kvs_int_t uIdx = 0; + kvs_int_t uSize = a->size(); + while(uIdx < uSize) + { + KviKvsVariant * v = a->at(uIdx); + if(v) + { + QString tmp; + v->asString(tmp); + szColumns.append(tmp); + } + else szColumns.append(""); + uIdx++; + } + } + ((QTableWidget *)object())->setHorizontalHeaderLabels(szColumns); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,setVerticalHeaderLabels) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsArrayCast ac; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("labels",KVS_PT_ARRAYCAST,0,ac) + KVSO_PARAMETERS_END(c) + QStringList szColumns; + if(KviKvsArray * a = ac.array()) + { + kvs_int_t uIdx = 0; + kvs_int_t uSize = a->size(); + while(uIdx < uSize) + { + KviKvsVariant * v = a->at(uIdx); + if(v) + { + QString tmp; + v->asString(tmp); + szColumns.append(tmp); + } + else szColumns.append(""); + uIdx++; + } + } + ((QTableWidget *)object())->setVerticalHeaderLabels(szColumns); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,setCellWidget) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsObject * pObject; + kvs_hobject_t hObject; + kvs_uint_t uRow,uCol; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) + KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + CHECK_HOBJECT_IS_WIDGET(pObject) + ((QTableWidget *)object())->setCellWidget(uRow,uCol,((QWidget *)(pObject->object()))); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,hideHorizontalHeader) +{ + Q_UNUSED(c); + ((QTableWidget *)widget())->horizontalHeader()->hide(); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,hideVerticalHeader) +{ + Q_UNUSED(c); + ((QTableWidget *)widget())->verticalHeader()->hide(); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,showHorizontalHeader) +{ + Q_UNUSED(c); + ((QTableWidget *)widget())->horizontalHeader()->show(); + return true; +} + +KVSO_CLASS_FUNCTION(tableWidget,showVerticalHeader) +{ + Q_UNUSED(c); + ((QTableWidget *)widget())->verticalHeader()->show(); + return true; +} +KVSO_CLASS_FUNCTION(tableWidget,setItemFlags) +{ + CHECK_INTERNAL_POINTER(widget()) + + QStringList itemflags; + kvs_uint_t iRow,iCol; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,iRow) + KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,iCol) + KVSO_PARAMETER("flags",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,itemflags) + KVSO_PARAMETERS_END(c) + int flag,sum=0; + for ( int i=0;isetCheckState(0,Qt::Unchecked); + sum = sum | flag; + } else { + c->warning(__tr2qs_ctx("Unknown item flag '%Q'","objects"),&itemflags.at(i)); + } + } + QTableWidgetItem *pItem=((QTableWidget *)widget())->item(iRow,iCol); + if(pItem) pItem->setFlags((Qt::ItemFlags)sum); + return true; +} + +void KvsObject_tableWidget::slotItemEntered(QTableWidgetItem * i) +{ + KviKvsVariantList params(new KviKvsVariant((kvs_int_t)i->row()),new KviKvsVariant((kvs_int_t)i->column())); + callFunction(this,"itemEnteredEvent",0,¶ms); +} + +KVSO_CLASS_FUNCTION(tableWidget,itemEnteredEvent) +{ + emitSignal("itemEntered",c,c->params()); + return true; +} + +void KvsObject_tableWidget::cellActivated(int iRow,int iCol) +{ + KviKvsVariantList params(new KviKvsVariant((kvs_int_t)iRow),new KviKvsVariant((kvs_int_t)iCol)); + callFunction(this,"cellActivatedEvent",0,¶ms); +} + +KVSO_CLASS_FUNCTION(tableWidget,cellActivatedEvent) +{ + emitSignal("cellActivated",c,c->params()); + return true; +} + +void KvsObject_tableWidget::cellDoubleClicked(int iRow,int iCol) +{ + KviKvsVariantList params(new KviKvsVariant((kvs_int_t)iRow),new KviKvsVariant((kvs_int_t)iCol)); + callFunction(this,"cellDoubleClickedEvent",0,¶ms); +} + +KVSO_CLASS_FUNCTION(tableWidget,cellDoubleClickedEvent) +{ + emitSignal("cellDoubleClicked",c,c->params()); + return true; +} +bool KvsObject_tableWidget::paint(QPainter * p, const QStyleOptionViewItem & option, const QModelIndex & index) +{ + p->save(); + KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass("painter"); + KviKvsVariantList params; + KviKvsObject * pObject = pClass->allocateInstance(0,"internalpainter",m_pContext,¶ms); + ((KvsObject_painter *)pObject)->setInternalPainter(p); + p->setClipRect(option.rect); + p->translate(option.rect.x(),option.rect.y()); + int col=index.column(); + int row=index.row(); + kvs_hobject_t handle=pObject->handle(); + kvs_int_t cell_height=(kvs_int_t)option.rect.height(); + kvs_int_t cell_width=(kvs_int_t)option.rect.width(); + KviKvsVariantList parameters(new KviKvsVariant(handle),new KviKvsVariant((kvs_int_t) row),new KviKvsVariant((kvs_int_t) col),new KviKvsVariant(cell_width),new KviKvsVariant(cell_height)); + bool ret=false; + KviKvsVariant *retv=new KviKvsVariant(ret); + callFunction(this,"paintCellEvent",retv,¶meters); + pObject=KviKvsKernel::instance()->objectController()->lookupObject(handle); + if (pObject) pObject->dieNow(); + p->restore(); + return retv->asBoolean(); +} + +KviCellItemDelegate::KviCellItemDelegate(QAbstractItemView * pWidget,KvsObject_tableWidget * parent) +: QItemDelegate(pWidget), m_pParentScript(parent) +{ +} + +KviCellItemDelegate::~KviCellItemDelegate() +{ +} + +void KviCellItemDelegate::paint(QPainter * pPainter, const QStyleOptionViewItem & option, const QModelIndex & index) const +{ + if (m_pParentScript->paint(pPainter,option,index)) + QItemDelegate::paint(pPainter,option,index); +} + +QSize KviCellItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex & index) const +{ + KviKvsVariant *sizeret=new KviKvsVariant(); + //qDebug("sizehint cell"); + KviKvsVariantList parameters(new KviKvsVariant((kvs_int_t) index.row()),new KviKvsVariant((kvs_int_t) index.column())); + m_pParentScript->callFunction(m_pParentScript,"sizeHintCellRequestEvent",sizeret,¶meters); + if (sizeret->isArray()) + { + if (sizeret->array()->size()==2) + { + kvs_int_t w,h; + if (sizeret->array()->at(0)->asInteger(w) && sizeret->array()->at(1)->asInteger(h))return QSize(w,h); + } + } + return QItemDelegate::sizeHint(option,index); +} + + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_tableWidget.moc" +#endif //COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/objects/KvsObject_tableWidget.h b/src/modules/objects/KvsObject_tableWidget.h new file mode 100644 index 000000000..a0c5df848 --- /dev/null +++ b/src/modules/objects/KvsObject_tableWidget.h @@ -0,0 +1,116 @@ +#ifndef _CLASS_TABLEWIDGET_H_ +#define _CLASS_TABLEWIDGET_H_ +//============================================================================= +// +// File : KvsObject_tableWidget.h +// Creation date : Wed 4 Feb 2009 09:30:05 CEST by Carbone Alessandro +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000 Krzysztof Godlewski +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_widget.h" +#include "object_macros.h" + +#include "KviKvsRunTimeContext.h" + +#include +#include +#include +#include + +class KvsObject_tableWidget; + +class KviCellItemDelegate : public QItemDelegate +{ +public: + KviCellItemDelegate(QAbstractItemView * pWidget = 0,KvsObject_tableWidget *pParent=0); + ~KviCellItemDelegate(); +protected: +// QAbstractItemView * m_pParent; + KvsObject_tableWidget *m_pParentScript; +public: + QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const; + void paint(QPainter * pPainter, const QStyleOptionViewItem & option, const QModelIndex & index) const; +}; + +class KvsObject_tableWidget : public KvsObject_widget +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_tableWidget) +public: + QWidget * widget() { return (QWidget *)object(); }; + bool paint(QPainter * pPainter, const QStyleOptionViewItem & option, const QModelIndex & index); + +protected: + QSqlQueryModel * model; + KviKvsRunTimeContext * m_pContext; + KviCellItemDelegate * m_pCellItemDelegate; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool setText(KviKvsObjectFunctionCall *c); + bool setNumber(KviKvsObjectFunctionCall *c); + bool setToolTip(KviKvsObjectFunctionCall *c); + bool text(KviKvsObjectFunctionCall *c); + bool setIcon(KviKvsObjectFunctionCall *c); + bool setItemFlags(KviKvsObjectFunctionCall *c); + + bool setColumnCount(KviKvsObjectFunctionCall *c); + bool columnCount(KviKvsObjectFunctionCall *c); + bool setRowCount(KviKvsObjectFunctionCall *c); + bool currentRow(KviKvsObjectFunctionCall *c); + bool currentColumn(KviKvsObjectFunctionCall *c); + bool itemRowColAt(KviKvsObjectFunctionCall *c); + + bool rowCount(KviKvsObjectFunctionCall *c); + + bool insertRow(KviKvsObjectFunctionCall *c); + bool insertColumn(KviKvsObjectFunctionCall *c); + bool removeRow(KviKvsObjectFunctionCall *c); + bool removeColumn(KviKvsObjectFunctionCall *c); + + + bool setHorizontalHeaderLabels(KviKvsObjectFunctionCall *c); + bool setVerticalHeaderLabels(KviKvsObjectFunctionCall *c); + bool setCellWidget(KviKvsObjectFunctionCall *c); + + bool hideHorizontalHeader(KviKvsObjectFunctionCall *c); + bool showHorizontalHeader(KviKvsObjectFunctionCall *c); + bool hideVerticalHeader(KviKvsObjectFunctionCall *c); + bool showVerticalHeader(KviKvsObjectFunctionCall *c); + bool clear(KviKvsObjectFunctionCall *c); + bool itemEnteredEvent(KviKvsObjectFunctionCall *c); + bool cellActivatedEvent(KviKvsObjectFunctionCall *c); + bool cellDoubleClickedEvent(KviKvsObjectFunctionCall *c); + + bool hideColumn(KviKvsObjectFunctionCall *c); + bool showColumn(KviKvsObjectFunctionCall *c); + bool hideRow(KviKvsObjectFunctionCall *c); + bool showRow(KviKvsObjectFunctionCall *c); + bool resizeRowsToContents(KviKvsObjectFunctionCall *c); + bool resizeColumnsToContents(KviKvsObjectFunctionCall *c); +protected slots: + void slotItemEntered(QTableWidgetItem *); + void cellActivated(int iRow,int iCol); + void cellDoubleClicked(int iRow,int iCol); +}; + +#endif // !_CLASS_TABLEWIDGET_H_ diff --git a/src/modules/objects/KvsObject_textBrowser.cpp b/src/modules/objects/KvsObject_textBrowser.cpp new file mode 100644 index 000000000..44fb40973 --- /dev/null +++ b/src/modules/objects/KvsObject_textBrowser.cpp @@ -0,0 +1,155 @@ +//============================================================================= +// +// File : KvsObject_textBrowser.cpp +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include "KvsObject_textBrowser.h" +#include "KviError.h" +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KviIconManager.h" + +#include +#include +#include +/* + @doc: textBrowser + @keyterms: + textBrowser browser widget class, + @title: + textBrowser class + @type: + class + @short: + Provides a class that can display html pages. + @inherits: + [class]widget[/class] + @description: + Provides a class that can display html pages with hypertext navigation. + @functions: + !fn: $setSource() + With this you can display the page at szFile location (szFile include the path). + !fn: $backward() + Changes the document displayed to the previous document in the list of documents built by navigating links. + !fn: $forward() + Changes the document displayed to the next document in the list of documents built by navigating links. + !fn: $home() + Changes the document displayed to be the first document the browser displayed. + !fn: $reload() + Reloads the current set source. + !fn: $linkClickedEvent() + Triggered when a link is clicked by the user. The default implementation of this function + emits the "linkClicked" signal. + @signals: + !sg: $linkClicked() + This signal is emitted by the default implementation of the [classfnc]$linkClickedEvent[/classfnc]() function. +*/ + +KVSO_BEGIN_REGISTERCLASS(KvsObject_textBrowser,"textBrowser","multilineedit") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_textBrowser,setSource) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_textBrowser,forward) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_textBrowser,backward) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_textBrowser,home) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_textBrowser,reload) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_textBrowser,linkClickedEvent) +KVSO_END_REGISTERCLASS(KvsObject_textBrowser) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_textBrowser,KvsObject_textedit) + +KVSO_END_CONSTRUCTOR(KvsObject_textBrowser) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_textBrowser) + +KVSO_END_CONSTRUCTOR(KvsObject_textBrowser) + +bool KvsObject_textBrowser::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + SET_OBJECT(QTextBrowser); + connect(obj,SIGNAL(anchorClicked(const QUrl &)),this,SLOT(anchorClicked(const QUrl &))); + return true; +} + +KVSO_CLASS_FUNCTION(textBrowser,setSource) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szFile; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("file_name",KVS_PT_STRING,0,szFile) + KVSO_PARAMETERS_END(c) + if(!QFile::exists(szFile)) + { + c->warning(__tr2qs_ctx("I can't find the specified file '%Q'.","objects"),&szFile); + return true; + } + QUrl url; + url.setPath(szFile); + ((QTextBrowser *)widget())->setSource(url); + return true; +} + +KVSO_CLASS_FUNCTION(textBrowser,forward) +{ + CHECK_INTERNAL_POINTER(widget()) + ((QTextBrowser *)widget())->forward(); + return true; +} + +KVSO_CLASS_FUNCTION(textBrowser,backward) +{ + CHECK_INTERNAL_POINTER(widget()) + ((QTextBrowser *)widget())->backward(); + return true; +} + +KVSO_CLASS_FUNCTION(textBrowser,home) +{ + CHECK_INTERNAL_POINTER(widget()) + ((QTextBrowser *)widget())->home(); + return true; +} + +KVSO_CLASS_FUNCTION(textBrowser,reload) +{ + CHECK_INTERNAL_POINTER(widget()) + ((QTextBrowser *)widget())->reload(); + return true; +} + +void KvsObject_textBrowser::anchorClicked(const QUrl &url) +{ + KviKvsVariantList parms(new KviKvsVariant(url.path())); + callFunction(this,"linkClickedEvent",0,&parms); +} + +KVSO_CLASS_FUNCTION(textBrowser,linkClickedEvent) +{ + emitSignal("linkClicked",c,c->params()); + return true; +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_textBrowser.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES + diff --git a/src/modules/objects/KvsObject_textBrowser.h b/src/modules/objects/KvsObject_textBrowser.h new file mode 100644 index 000000000..50645e6f3 --- /dev/null +++ b/src/modules/objects/KvsObject_textBrowser.h @@ -0,0 +1,53 @@ +#ifndef _CLASS_TBROWSER_H_ +#define _CLASS_TBROWSER_H_ +//============================================================================= +// +// File : KvsObject_textBrowser.h +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_widget.h" +#include "KvsObject_multiLineEdit.h" +#include "object_macros.h" +#include + +class KvsObject_textBrowser : public KvsObject_textedit +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_textBrowser) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool setSource(KviKvsObjectFunctionCall *c); + bool forward(KviKvsObjectFunctionCall *c); + bool backward(KviKvsObjectFunctionCall *c); + bool home(KviKvsObjectFunctionCall *c); + bool reload(KviKvsObjectFunctionCall *c); + bool linkClickedEvent(KviKvsObjectFunctionCall *c); +protected slots: + void anchorClicked(const QUrl &); +}; + +#endif //!_CLASS_TBROWSER_H_ diff --git a/src/modules/objects/KvsObject_toolBar.cpp b/src/modules/objects/KvsObject_toolBar.cpp new file mode 100644 index 000000000..4dbacc19b --- /dev/null +++ b/src/modules/objects/KvsObject_toolBar.cpp @@ -0,0 +1,128 @@ +//============================================================================= +// +// File : KvsObject_toolBar.cpp +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_toolBar.h" +#include "KviError.h" +#include "kvi_debug.h" +#include "KviTalToolBar.h" +#include "KviTalMainWindow.h" +#include "KviLocale.h" +#include "KviIconManager.h" +#include "KvsObject_mainWindow.h" + +/* + @doc: toolbar + @keyterms: + toolbar object class, + @title: + toolbar class + @type: + class + @short: + Provides a toolbar for mainwindow widget. + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + The toolbar class provides a movable panel containing widgets such as tool buttons. + @functions: + !fn: $addSeparator() + Adds a separator to the right/bottom of the toolbar. + !fn: $setLabel() + Sets the toolbar's label. + !fn: $label() + Returns the toolbar's label. + !fn: $clear() + Deletes all the toolbar's child widgets. + +*/ + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_toolBar,"toolbar","widget") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolBar,addSeparator) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolBar,setLabel) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolBar,label) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolBar,clear) +KVSO_END_REGISTERCLASS(KvsObject_toolBar) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_toolBar,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_toolBar) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_toolBar) + +KVSO_END_CONSTRUCTOR(KvsObject_toolBar) + +bool KvsObject_toolBar::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *) +{ + if (!parentObject()) + { + pContext->warning(__tr2qs_ctx("The toolbar cannot be a parent-widget!","objects")); + return true; + } + if(parentObject()->inheritsClass("mainwindow")) + { + setObject(new KviTalToolBar(getName(), ((KviTalMainWindow *)parentScriptWidget())), true); + } + else + { + pContext->warning(__tr2qs_ctx("The parent-widget isn't a MainWindow.","objects")); + } + + return true; +} + +KVSO_CLASS_FUNCTION(toolBar,addSeparator) +{ + CHECK_INTERNAL_POINTER(widget()) + ((KviTalToolBar *)widget())->addSeparator(); + return true; +} +KVSO_CLASS_FUNCTION(toolBar,setLabel) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szLabel; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel) + KVSO_PARAMETERS_END(c) + ((KviTalToolBar *)widget())->setWindowTitle(szLabel); + return true; +} +KVSO_CLASS_FUNCTION(toolBar,label) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setString(((KviTalToolBar *)widget())->windowTitle()); + return true; +} +KVSO_CLASS_FUNCTION(toolBar,clear) +{ + CHECK_INTERNAL_POINTER(widget()) + ((KviTalToolBar *)object())->clear(); + return true; +} + + + diff --git a/src/modules/objects/KvsObject_toolBar.h b/src/modules/objects/KvsObject_toolBar.h new file mode 100644 index 000000000..ad537df43 --- /dev/null +++ b/src/modules/objects/KvsObject_toolBar.h @@ -0,0 +1,48 @@ +#ifndef _CLASS_TOOLBAR_H_ +#define _CLASS_TOOLBAR_H_ +//============================================================================= +// +// File : KvsObject_toolBar.h +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_widget.h" +#include "object_macros.h" + +class KvsObject_toolBar : public KvsObject_widget +{ +public: + KVSO_DECLARE_OBJECT(KvsObject_toolBar) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool addSeparator(KviKvsObjectFunctionCall *c); + bool setLabel(KviKvsObjectFunctionCall *c); + bool label(KviKvsObjectFunctionCall *c); + bool setStretchableWidget(KviKvsObjectFunctionCall *c); + bool clear(KviKvsObjectFunctionCall *c); +}; + + +#endif //!_CLASS_TOOLBAR_H_ diff --git a/src/modules/objects/KvsObject_toolButton.cpp b/src/modules/objects/KvsObject_toolButton.cpp new file mode 100644 index 000000000..884a3e92d --- /dev/null +++ b/src/modules/objects/KvsObject_toolButton.cpp @@ -0,0 +1,344 @@ +//============================================================================= +// +// File : KvsObject_toolButton.cpp +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_toolButton.h" +#include "KviError.h" +#include "kvi_debug.h" + +#include "KviLocale.h" +#include "KviIconManager.h" +#include "KviTalPopupMenu.h" +/* + @doc: toolbutton + @keyterms: + toolbutton object class, + @title: + toolbutton class + @type: + class + @short: + Provides a toolbutton for toolbar widget. + @inherits: + [class]object[/class] + [class]widget[/class] + @description: + The toolbutton class provides a quick-access button to commands or options, usually used inside a ToolBar. + @functions: + !fn:$setImage() + Sets the image for this button. + !fn:$setUsesBigPixmap() + Sets whether this toolbutton uses big pixmaps to enable. + !fn:$usesBigPixmap() + This property holds whether this toolbutton uses big pixmaps. + !fn:setUsesTextLabel() + Sets whether the toolbutton show a texlabel below the pixmap of the button. + !fn:$usesTextLabel() + Return 1 if the setUsesTextLabel is enabled, otherwise return 0. + !fn:$setTextLabel(,[tooltip:string]) + Sets the label of this button to and automatically sets it as a tool tip if is TRUE. + !fn: $textLabel() + Returns the label of tthe button. + !fn:$setAutoRaise() + Sets whether auto-raising is enabled. + !fn: $autoRaise() + Returns 1 if autoRaise is enabled, otherwise returns 0. + !fn:$setToggleButton() + Sets whether the tool button is a toggle button 1 enable, 0 disable. + !fn: $toggle() + Toggles the state of the tool button. + !fn:$setOn() + Sets whether the tool button is on to the bool value: 1 enable, 0 disable. + !fn:$setPopup () + Associates the given with this tool button. + !fn:$openPopup() + Opens the associated popup menu. If there is no such menu, this function does nothing. + !fn:setTextPosition() + Sets the position of the tool button's textLabel in relation to the tool button's icon.[br] + Valid texpos values are:[br] + - BesideIcon : The text appears beside the icon.[br] + - BelowIcon : The text appears below the icon. + !fn: $textPosition() + Returns the position of the text label of this button. + !fn: $clickEvent() + This function is called when the toolbutton is clicked.[br] + You can reimplement it to handle the user click events.[br] + The default implementation emits the [classfnc]$clicked[/classfnc]() signal. + @signals: + !sg: $clicked() + This signal is emitted by the default implementation of [classfnc]$clickEvent[/classfnc]().[br] +*/ + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_toolButton,"toolbutton","widget") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolButton,setImage) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolButton,setUsesBigPixmap) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolButton,usesBigPixmap) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolButton,setUsesTextLabel) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolButton,usesTextLabel) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolButton,setAutoRaise) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolButton,autoRaise) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolButton,setTextLabel) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolButton,textLabel) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolButton,setPopup) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolButton,openPopup) + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolButton,setToggleButton) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolButton,toggle) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolButton,setOn) + + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolButton,setTextPosition) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolButton,textPosition) + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_toolButton,clickEvent) +KVSO_END_REGISTERCLASS(KvsObject_toolButton) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_toolButton,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_toolButton) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_toolButton) + +KVSO_END_CONSTRUCTOR(KvsObject_toolButton) + +bool KvsObject_toolButton::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + SET_OBJECT(QToolButton); + connect(widget(),SIGNAL(clicked()),this,SLOT(slotClicked())); + return true; +} + +KVSO_CLASS_FUNCTION(toolButton,setImage) +{ + CHECK_INTERNAL_POINTER(widget()) + QString icon; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("icon_id",KVS_PT_STRING,0,icon) + KVSO_PARAMETERS_END(c) + QPixmap * pix = g_pIconManager->getImage(icon); + if(pix){ + ((QToolButton *)widget())->setIcon(QIcon(*pix)); + } + else + ((QToolButton *)widget())->setIcon(QIcon()); + return true; +} + +KVSO_CLASS_FUNCTION(toolButton,setUsesBigPixmap) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + ((QToolButton *)widget())->setIconSize(bEnabled ? QSize(32,32) : QSize(22,22)); + return true; +} + +KVSO_CLASS_FUNCTION(toolButton,usesBigPixmap) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setBoolean(((QToolButton *)widget())->iconSize().height() > 22); + return true; +} + +KVSO_CLASS_FUNCTION(toolButton,setUsesTextLabel) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + ((QToolButton *)widget())->setToolButtonStyle(bEnabled?Qt::ToolButtonTextUnderIcon : Qt::ToolButtonIconOnly); + return true; +} + +KVSO_CLASS_FUNCTION(toolButton,usesTextLabel) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setBoolean(((QToolButton *)widget())->toolButtonStyle() != Qt::ToolButtonIconOnly); + return true; +} + +KVSO_CLASS_FUNCTION(toolButton,setAutoRaise) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + ((QToolButton *)widget())->setAutoRaise(bEnabled); + return true; +} + +KVSO_CLASS_FUNCTION(toolButton,autoRaise) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setBoolean(((QToolButton *)widget())->autoRaise()); + return true; +} + +KVSO_CLASS_FUNCTION(toolButton,setOn) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + ((QToolButton *)widget())->setChecked(bEnabled); + return true; +} + +KVSO_CLASS_FUNCTION(toolButton,setToggleButton) +{ + CHECK_INTERNAL_POINTER(widget()) + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + ((QToolButton *)widget())->setCheckable(bEnabled); + return true; +} + +KVSO_CLASS_FUNCTION(toolButton,toggle) +{ + CHECK_INTERNAL_POINTER(widget()) + ((QToolButton *)widget())->toggle(); + return true; +} + +KVSO_CLASS_FUNCTION(toolButton,setTextLabel) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szLabel,szTip; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel) + KVSO_PARAMETER("tooltip",KVS_PT_STRING,KVS_PF_OPTIONAL,szTip) + KVSO_PARAMETERS_END(c) + ((QToolButton *)widget())->setText(szLabel); + if (!szTip.isEmpty()) ((QToolButton *)widget())->setToolTip(szTip); + return true; +} + +KVSO_CLASS_FUNCTION(toolButton,textLabel) +{ + CHECK_INTERNAL_POINTER(widget()) + c->returnValue()->setString(((QToolButton *)widget())->text()); + return true; +} + +KVSO_CLASS_FUNCTION(toolButton,setPopup) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsObject *ob; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETERS_END(c) + ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + if (!ob) + { + c->warning(__tr2qs_ctx("Widget parameter is not an object","objects")); + return true; + } + if (!ob->object()) + { + c->warning(__tr2qs_ctx("Widget parameter is not a valid object","objects")); + return true; + } + if(!ob->inheritsClass("popupmenu")) + { + c->warning(__tr2qs_ctx("Can't add a non-popupmenu object","objects")); + return true; + } + ((QToolButton *)widget())->setMenu(((KviTalPopupMenu *)(ob->object()))); + return true; +} + +KVSO_CLASS_FUNCTION(toolButton,openPopup) +{ + CHECK_INTERNAL_POINTER(widget()) + ((QToolButton *)widget())->showMenu(); + return true; +} +/* +KVSO_CLASS_FUNCTION(toolButton,setPopupDelay) +{ + kvs_int_t uDelay; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("delay",KVS_PT_UNSIGNEDINTEGER,0,uDelay) + KVSO_PARAMETERS_END(c) + if (widget()) + ((QToolButton *)widget())->setPopupDelay(uDelay); + return true; +} +KVSO_CLASS_FUNCTION(toolButton,popupDelay) +{ + if (widget()) + c->returnValue()->setInteger(((QToolButton *)widget())->popupDelay()); + return true; +} +*/ +KVSO_CLASS_FUNCTION(toolButton,setTextPosition) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szPos; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("position",KVS_PT_STRING,0,szPos) + KVSO_PARAMETERS_END(c) + if(KviQString::equalCI(szPos,"BesideIcon")) + ((QToolButton *)widget())->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + else if(KviQString::equalCI(szPos,"BelowIcon")) + ((QToolButton *)widget())->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + else c->warning(__tr2qs_ctx("Unknown text position '%Q'","objects"),&szPos); + return true; +} + +KVSO_CLASS_FUNCTION(toolButton,textPosition) +{ + CHECK_INTERNAL_POINTER(widget()) + QString szPos="BelowIcon"; + if ((((QToolButton *)widget())->toolButtonStyle())==(Qt::ToolButtonTextBesideIcon)) + szPos="BesideIcon"; + c->returnValue()->setString(szPos); + return true; +} + +KVSO_CLASS_FUNCTION(toolButton,clickEvent) +{ + emitSignal("clicked",c); + return true; +} + +void KvsObject_toolButton::slotClicked() +{ + KviKvsVariantList *params=0; + callFunction(this,"clickEvent",params); +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_toolButton.moc" +#endif //COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/objects/KvsObject_toolButton.h b/src/modules/objects/KvsObject_toolButton.h new file mode 100644 index 000000000..041b5612b --- /dev/null +++ b/src/modules/objects/KvsObject_toolButton.h @@ -0,0 +1,70 @@ +#ifndef _CLASS_TOOLBUTTON_H_ +#define _CLASS_TOOLBUTTON_H_ +//============================================================================= +// +// File : KvsObject_toolButton.cpp +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + + +#include "KvsObject_widget.h" +#include "object_macros.h" + +class KvsObject_toolButton : public KvsObject_widget +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_toolButton) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool setImage(KviKvsObjectFunctionCall *c); + bool setUsesBigPixmap(KviKvsObjectFunctionCall *c); + bool usesBigPixmap(KviKvsObjectFunctionCall *c); + bool setUsesTextLabel(KviKvsObjectFunctionCall *c); + bool usesTextLabel(KviKvsObjectFunctionCall *c); + bool setTextLabel(KviKvsObjectFunctionCall *c); + bool textLabel(KviKvsObjectFunctionCall *c); + bool setPopup(KviKvsObjectFunctionCall *c); + bool openPopup(KviKvsObjectFunctionCall *c); + bool setOn(KviKvsObjectFunctionCall *c); + bool setToggleButton(KviKvsObjectFunctionCall *c); + bool toggle(KviKvsObjectFunctionCall *c); +// bool setPopupDelay(KviKvsObjectFunctionCall *c); +// bool popupDelay(KviKvsObjectFunctionCall *c); + bool setTextPosition(KviKvsObjectFunctionCall *c); + bool textPosition(KviKvsObjectFunctionCall *c); + + bool setAutoRaise(KviKvsObjectFunctionCall *c); + bool autoRaise(KviKvsObjectFunctionCall *c); + bool clickEvent(KviKvsObjectFunctionCall *c); +signals: + void clicked(); +protected slots: + void slotClicked(); +}; + + +#endif //!_CLASS_TOOLBUTTON_H_ diff --git a/src/modules/objects/KvsObject_trayIcon.cpp b/src/modules/objects/KvsObject_trayIcon.cpp new file mode 100644 index 000000000..67fb17c43 --- /dev/null +++ b/src/modules/objects/KvsObject_trayIcon.cpp @@ -0,0 +1,243 @@ +//============================================================================= +// +// File : KvsObject_trayIcon.cpp +// Creation date : Wed Ago 25 17:28:45 2010 GMT by Carbone Alesssandro +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2009 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_trayIcon.h" +#include "KvsObject_popupMenu.h" +#include "KviIconManager.h" +#include "kvi_debug.h" +#include "KviError.h" +#include "KviLocale.h" + +#include + + + + +/* + @doc: trayicon + @keyterms: + trayicon object class + @title: + trayicon class + @type: + class + @short: + An implementation of the the system tray icon. + @inherits: + [class]object[/class] + @description: + This class provides a standard trayicon functionality.[br] + @functions: + !fn: setIcon(). + Sets the tray icon. + See the [doc:image_id]image identifier[/doc] documentation for the explaination of the parameter. + !fn: setTooltip(). + Sets the tray icon tooltip. + !fn: show() + Shows the tray icon. + !fn: hide() + Hides the tray icon. + !fn: isVisible() + Returns '1' if the tray icon is currently visible. + !fn: showMessage(,,,) + Shows a balloon message for the entry with the given title, message and message_icon for the time specified in millisecondsTimeoutHint. title and message must be plain text strings. + Message can be clicked by the user; the messageClickedEvent() will be triggered when this occurs. + Valid values for message_icon are: + - NoIcon : No icon is shown. + - Information : An information icon is shown. + - Warning : A standard warning icon is shown. + - Critical : A critical warning icon is shown. + !fn: setContextMenu(). + Associates the given with the tray icon. + !fn: activatedEvent() + This event is triggered when the user click the tray icon. + If you reimplement this function the reason parameter will be passed as $0. + Values for reason are: + - Unknown : Unknown reason. + - Context : The context menu for the tray icon was requested. + - DoubleClick : The tray icon was double clicked. + - Trigger : The tray icon was clicked. + - MiddleClick : The tray icon was clicked with the middle mouse button. + The default implementation emits the [classfnc]$activated[/classfnc]() signal. + !fn: messageClickedEvent() + This event is triggered when the message displayed using [classfnc]$showMessage[/classfnc]() was clicked by the user. + The default implementation emits the [classfnc]$messageClicked[/classfnc]() signal. + + + @signals: + !sg: $activated() + This signal is emitted by the default implementation of [classfnc]$activatedEvent[/classfnc]. + !sg: $messageClicked() + This signal is emitted by the default implementation of [classfnc]$messageClickedEvent[/classfnc]. +*/ + +KVSO_BEGIN_REGISTERCLASS(KvsObject_trayIcon,"trayicon","object") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_trayIcon,show) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_trayIcon,hide) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_trayIcon,isVisible) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_trayIcon,setIcon) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_trayIcon,setTooltip) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_trayIcon,showMessage) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_trayIcon,setContextMenu) + // events + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_trayIcon,activatedEvent) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_trayIcon,messageClickedEvent) +KVSO_END_REGISTERCLASS(KvsObject_trayIcon) + + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_trayIcon,KviKvsObject) + m_pTrayIcon = new QSystemTrayIcon(0); + connect(m_pTrayIcon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(slotActivated(QSystemTrayIcon::ActivationReason))); + connect(m_pTrayIcon,SIGNAL(messageClicked()),this,SLOT(slotMessageClicked())); + +KVSO_END_CONSTRUCTOR(KvsObject_trayIcon) + +KVSO_BEGIN_DESTRUCTOR(KvsObject_trayIcon) + delete m_pTrayIcon; +KVSO_END_DESTRUCTOR(KvsObject_trayIcon) + + +KVSO_CLASS_FUNCTION(trayIcon,setIcon) +{ + CHECK_INTERNAL_POINTER(m_pTrayIcon) + QString szIcon; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("icon",KVS_PT_STRING,0,szIcon) + KVSO_PARAMETERS_END(c) + QPixmap * pix = g_pIconManager->getImage(szIcon); + if(pix) m_pTrayIcon->setIcon(*pix); + return true; +} +KVSO_CLASS_FUNCTION(trayIcon,setTooltip) +{ + CHECK_INTERNAL_POINTER(m_pTrayIcon) + QString szTooltip; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("icon",KVS_PT_STRING,0,szTooltip) + KVSO_PARAMETERS_END(c) + m_pTrayIcon->setToolTip(szTooltip); + return true; +} +KVSO_CLASS_FUNCTION(trayIcon,show) +{ + CHECK_INTERNAL_POINTER(m_pTrayIcon) + m_pTrayIcon->show(); + return true; +} +KVSO_CLASS_FUNCTION(trayIcon,hide) +{ + CHECK_INTERNAL_POINTER(m_pTrayIcon) + m_pTrayIcon->show(); + return true; +} +KVSO_CLASS_FUNCTION(trayIcon,isVisible) +{ + CHECK_INTERNAL_POINTER(m_pTrayIcon) + c->returnValue()->setBoolean(m_pTrayIcon->isVisible()); + return true; +} + +KVSO_CLASS_FUNCTION(trayIcon,showMessage) +{ + CHECK_INTERNAL_POINTER(m_pTrayIcon) + QString szMessage,szTitle,szMessageIcon; + kvs_uint_t uTimeout; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("title",KVS_PT_STRING,0,szTitle) + KVSO_PARAMETER("message",KVS_PT_STRING,0,szMessage) + KVSO_PARAMETER("icon",KVS_PT_STRING,0,szMessageIcon) + KVSO_PARAMETER("timeout",KVS_PT_UINT,0,uTimeout) + KVSO_PARAMETERS_END(c) + QSystemTrayIcon::MessageIcon message=QSystemTrayIcon::NoIcon; + if(KviQString::equalCI(szMessageIcon,"NoIcon")) message= QSystemTrayIcon::NoIcon; + else if(KviQString::equalCI(szMessageIcon,"Information"))message= QSystemTrayIcon::Information; + else if(KviQString::equalCI(szMessageIcon,"Warning")) message= QSystemTrayIcon::Warning; + else if(KviQString::equalCI(szMessageIcon,"Critical")) message= QSystemTrayIcon::Critical; + else c->warning(__tr2qs_ctx("Invalid message Icon: switch to default NoIcon '%Q'","objects"),&szMessageIcon); + m_pTrayIcon->showMessage(szTitle,szMessage,message,uTimeout); + return true; +} + +KVSO_CLASS_FUNCTION(trayIcon,setContextMenu) +{ + CHECK_INTERNAL_POINTER(m_pTrayIcon) + KviKvsObject *ob; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETERS_END(c) + ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + if (!ob) + { + c->warning(__tr2qs_ctx("Widget parameter is not an object","objects")); + return true; + } + if (!ob->object()) + { + c->warning(__tr2qs_ctx("Widget parameter is not a valid object","objects")); + return true; + } + if(!ob->inheritsClass("popupmenu")) + { + c->warning(__tr2qs_ctx("Can't add a non-popupmenu object","objects")); + return true; + } + m_pTrayIcon->setContextMenu(((QMenu *)(ob->object()))); + return true; +} +KVSO_CLASS_FUNCTION(trayIcon,activatedEvent) +{ + emitSignal("activated",c,c->params()); + return true; +} +KVSO_CLASS_FUNCTION(trayIcon,messageClickedEvent) +{ + emitSignal("messageClicked",c,c->params()); + return true; +} +void KvsObject_trayIcon::slotMessageClicked() +{ + KviKvsVariantList *lParams=0; + callFunction(this,"messageClickedEvent",0,lParams); +} + +void KvsObject_trayIcon::slotActivated(QSystemTrayIcon::ActivationReason reason) +{ + QString szReason; + if (reason==QSystemTrayIcon::Unknown) + szReason="Unknown"; + else if(reason==QSystemTrayIcon::Context) + szReason="Context"; + else if(reason==QSystemTrayIcon::DoubleClick) + szReason="DoubleClick"; + else if(reason==QSystemTrayIcon::Trigger) + szReason="Trigger"; + else szReason="MiddleClick"; + KviKvsVariantList lParams; + lParams.append(new KviKvsVariant(szReason)); + callFunction(this,"activatedEvent",0,&lParams); +} +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_trayIcon.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/objects/KvsObject_trayIcon.h b/src/modules/objects/KvsObject_trayIcon.h new file mode 100644 index 000000000..4bec98e67 --- /dev/null +++ b/src/modules/objects/KvsObject_trayIcon.h @@ -0,0 +1,58 @@ +#ifndef _CLASS_TRAYICON_H_ +#define _CLASS_TRAYICON_H_ +//============================================================================= +// +// File : KvsObject_trayIcon.h +// Creation date : Wed Ago 25 17:28:45 2010 GMT by Carbone Alesssandro +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + + + +//=============================================================== +#include "object_macros.h" +#include +#include + +class KvsObject_trayIcon : public KviKvsObject +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_trayIcon) +protected: + QSystemTrayIcon *m_pTrayIcon; +protected: + bool setIcon(KviKvsObjectFunctionCall *c); + bool show(KviKvsObjectFunctionCall *c); + bool hide(KviKvsObjectFunctionCall *c); + bool isVisible(KviKvsObjectFunctionCall *c); + bool setTooltip(KviKvsObjectFunctionCall *c); + bool showMessage(KviKvsObjectFunctionCall *c); + bool setContextMenu(KviKvsObjectFunctionCall *c); + bool activatedEvent(KviKvsObjectFunctionCall *c); + bool messageClickedEvent(KviKvsObjectFunctionCall *c); + + +protected slots: + void slotActivated(QSystemTrayIcon::ActivationReason); + void slotMessageClicked(); +}; +#endif //_CLASS_TRAYICON_H_ diff --git a/src/modules/objects/KvsObject_treeWidget.cpp b/src/modules/objects/KvsObject_treeWidget.cpp new file mode 100644 index 000000000..c12649bfb --- /dev/null +++ b/src/modules/objects/KvsObject_treeWidget.cpp @@ -0,0 +1,666 @@ +//============================================================================= +// +// File : KvsObject_treeWidget.cpp +// Creation date : Fri Jan 28 14:21:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_treeWidget.h" + +#include "KviError.h" +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KviIconManager.h" +#include + + #include + +#include +#include +#include +#include +#include + +/* + @doc: listview + @keyterms: + listview widget class + @title: + listview class + @type: + class + @short: + A listview widget class + @inherits: + [class]widget[/class] + @description: + It can display and control a hierarchy of multi-column items, and provides the ability to add new items at any time. + The items are added by creating children [class]listviewitem[/class] objects: simply allocating them with $new + will add the items to the listview and simply deleting them will remove them. + Allocating a [class]listviewtitem[/class] item2 as a child of item1 will insert it to the same listview creating + a subtree of items spannig from item1. The subtree can be opened or closed by a simple click either + on the parent item or on the little plus sign on the side of it (when [classfnc:listview]$setRootIsDecorated[/classfnc] + is set to $true. The listview can be in Single, Multi, Extended or NoSelection selection mode. + In single selection mode there can be only one selected item at a time and the selected item is also + the current item (this mode is the default). In Multi and Extended selection mode there can be multiple selected items + and the current item is one of them. The difference between Multi and Extended is in the way + that items can be selected by the mouse actions: experiment with the two modes :). + The NoSelection mode has obviously no selection at all. + @functions: + !fn: $addColumn(,[]) + Adds a width pixels wide column with the column header label to the list view. + + !fn: $setSorting(,) + Sets the list view to be sorted by column in ascending order if sort_order is "ascending" or descending order if it is "descending". + !fn: $setSortingEnabled() + If is true, user sorting is enabled for the tree. The default value is false. + In order to avoid performance issues, it is recommended that sorting is enabled after inserting the items into the tree. + !fn: $hideListViewHeader() + Hide the listview column header. + + !fn: $showListViewHeader() + Show the listview column header. + + !fn: $isListViewHeaderVisible() + Returns '1' if the listview header is currently visible. Otherwise this function returns '0'. + + !fn: $setAllColumnsShowFocus() + When the argument is $true, causes the listview to display the focus and selection + by highlighting all the columns of the item. When the argument is $false then + only the first column is selected/highlighted. + + !fn: $setSelectionMode() + Sets the selection mode for this listview. can be one of "Single","NoSelection","Multi" or "Extended". + + !fn: $selectedItems() + Returns the currently selected [class]listviewitem[/class] or $null if no items are selected. + This function works only if the list view is in single selection mode. + + !fn: $itemAt(,) + Returns the listviewitem object at the x,y globals coordinates or $null if no item at. + + !fn: $currentItem() + Returns the current [class]listviewitem[/class] or $null if no item is current at the moment. + + !fn: $firstChild() + Returns the first child [class]listviewitem[/class] of this listview or $null if there are no items at all. + + !fn: $topLevelItem() + Returns the child [class]listviewitem[/class] of this listview or $null if it does not exists. + + !fn: $topLevelItemCount() + Returns the number of top level items of this listview. + + !fn: setAcceptDrops() + If is true, user can drop files for this listview. The default value is true. + + !fn: $clickEvent() + This function is called when the user clicks in the list view. + In its argument the [class]listviewitem[/class] object clicked or 0 if the user didn't click on an item.[br] + The default implementation emits the [classfnc]$clicked[/classfnc]() signal. + + !fn: $selectionChangedEvent() + This event handle whenever the set of selected items has changed. + The argument is the newly selected item if the listview is in single selection mode.[br] + When the listview is in Multi or Extended selection mode then item is always $null.[br] + The default implementation emits the [classfnc]$selectionChanged[/classfnc]() signal. + + !fn: $currentChangedEvent() + This event are called whenever the current item has changed. + In its argument is the newly selected item or 0 if the change made no item current.[br] + The default implementation emits the [classfnc]$currentChanged[/classfnc]() signal. + + !fn: $itemActivatedEvent() + This s signal is emitted when the user activates an item by single- or double-clicking or pressing 'Enter'.[br] + In its argument the currrent item.[br] + The default implementation emits the [classfnc]$itemActivated[/classfnc]() signal. + + !fn: $spacePressedEvent() + This function is called by the framework when the space key is pressed.[br] + In its arument the currrent item.[br] + The default implementation emits the [classfnc]$spacePressed[/classfnc]() signal. + + !fn: $onItemEvent() + This event is called when an item has been expanded, i.e. when the children of item are shown. + The default implementation emits the [classfnc]$expanded[/classfnc]() signal. + + !fn: $itemCollapsedEvent() + This event is called when an item has been collapsed, i.e. when the children of item are hidden. + The default implementation emits the [classfnc]$collapsed[/classfnc]() signal. + + !fn: $itemChangedEvent(,,) + This event is called when the item has been renamed in text, e.g. by in in-place renaming, in column col.[br] + The default implementation emits the [classfnc]$itemChanged[/classfnc]() signal. + + + @signals: + !sg: $clicked() + This signal is emitted by the default implementation of [classfnc]$clickEvent[/classfnc](). + !sg: $selectionChanged() + This signal is emitted by the default implementation of [classfnc]$selectionChangedEvent[/classfnc](). + !sg: $currentChanged() + This signal is emitted by the default implementation of [classfnc]$currentChangedEvent[/classfnc](). + !sg: $itemActivated() + This signal is emitted by the default implementation of [classfnc]$itemActivatedEvent[/classfnc](). + !sg: $spacePressed() + This signal is emitted by the default implementation of [classfnc]$spacePredssedEvent[/classfnc](). + !sg: $onItem() + This signal is emitted by the default implementation of [classfnc]$onItemEvent[/classfnc](). + !sg: $itemExpanded() + This signal is emitted by the default implementation of [classfnc]$itemExpandedEvent[/classfnc](). + !sg: $itemCollapsed() + This signal is emitted by the default implementation of [classfnc]$itemCollapsedEvent[/classfnc](). + !sg: $itemChanged() + This signal is emitted by the default implementation of [classfnc]$itemChangedEvent[/classfnc](). + !sg: $rightButtonClicked() + This signal is emitted by the default implementation of [classfnc]$rightButtonClickedEvent[/classfnc](). + + +*/ + + + +//--------------------------------------------------------------------------------- + +KVSO_BEGIN_REGISTERCLASS(KvsObject_treeWidget,"listview","widget") + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,setHeaderLabels) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,addColumn) + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,setColumnText) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,setColumnCount) + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,setSorting) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,setSortingEnabled) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,setRootIsDecorated) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,setAllColumnsShowFocus) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,clear) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,selectedItems) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,currentItem) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,setSelectionMode) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,listViewHeaderIsVisible) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,itemAt) + + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,hideListViewHeader) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,showListViewHeader) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,firstChild) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,topLevelItem) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,topLevelItemCount) + + + + + //events + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,selectionChangedEvent); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,currentChangedEvent); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,itemActivatedEvent); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,onItemEvent); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,itemClickedEvent); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,itemExpandedEvent); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,itemCollapsedEvent); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,itemChangedEvent); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidget,setAcceptDrops); + KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KvsObject_treeWidget,"fileDroppedEvent") + +KVSO_END_REGISTERCLASS(KvsObject_treeWidget) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_treeWidget,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_treeWidget) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_treeWidget) + +KVSO_END_CONSTRUCTOR(KvsObject_treeWidget) + +bool KvsObject_treeWidget::init(KviKvsRunTimeContext *,KviKvsVariantList *) +{ + setObject(new KviKvsTreeWidget(parentScriptWidget(),getName().toUtf8().data(),this),true); + // hack for compatibility with "old" addColumn method; + ((QTreeWidget*) widget())->setColumnCount(0); + + connect(widget(),SIGNAL(itemClicked(QTreeWidgetItem *,int)),this,SLOT(slotClicked(QTreeWidgetItem *,int))); + connect(widget(),SIGNAL(itemSelectionChanged()),this,SLOT(slotSelectionChanged())); + connect(widget(),SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),this,SLOT(slotCurrentChanged(QTreeWidgetItem *,QTreeWidgetItem *))); + connect(widget(),SIGNAL(itemActivated(QTreeWidgetItem *,int)),this,SLOT(slotItemActivated(QTreeWidgetItem *,int))); + connect(widget(),SIGNAL(itemEntered(QTreeWidgetItem *,int)),this,SLOT(slotOnItemEntered(QTreeWidgetItem *,int))); + connect(widget(),SIGNAL(itemExpanded(QTreeWidgetItem *)),this,SLOT(slotItemExpanded(QTreeWidgetItem *))); + connect(widget(),SIGNAL(itemCollapsed(QTreeWidgetItem *)),this,SLOT(slotItemCollapsed(QTreeWidgetItem *))); + connect(widget(),SIGNAL(itemChanged(QTreeWidgetItem *,int)),this,SLOT(slotItemChanged(QTreeWidgetItem *,int))); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidget,setHeaderLabels) +{ + QStringList columns; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("labels",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,columns) + KVSO_PARAMETERS_END(c) + if (widget()){ + ((QTreeWidget *)object())->setHeaderLabels(columns); + } + return true; +} + +KVSO_CLASS_FUNCTION(treeWidget,setColumnText) +{ + if (!widget()) return true; + QString szLabel; + kvs_int_t iCol; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("column",KVS_PT_INT,0,iCol) + KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel) + KVSO_PARAMETERS_END(c) + QTreeWidgetItem *header=((QTreeWidget *)widget())->headerItem(); + header->setText(iCol,szLabel); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidget,topLevelItem) +{ + if (!widget()) return true; + kvs_int_t iIdx; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("index",KVS_PT_INT,0,iIdx) + KVSO_PARAMETERS_END(c) + QTreeWidgetItem *pItem=((QTreeWidget *)widget())->topLevelItem(iIdx); + if (!pItem) c->returnValue()->setHObject((kvs_hobject_t)0); + else c->returnValue()->setHObject(KvsObject_treeWidgetItem::itemToHandle(pItem)); + return true; +} +KVSO_CLASS_FUNCTION(treeWidget,itemAt) +{ + if (!widget()) return true; + kvs_int_t iXpos,iYpos; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("x_pos",KVS_PT_INT,0,iXpos) + KVSO_PARAMETER("y_pos",KVS_PT_INT,0,iYpos) + KVSO_PARAMETERS_END(c) + QPoint pPoint=((QTreeWidget *)widget())->viewport()->mapFromGlobal(QPoint(iXpos,iYpos)); + QTreeWidgetItem *pItem=((QTreeWidget *)widget())->itemAt(pPoint); + if (!pItem) c->returnValue()->setHObject((kvs_hobject_t)0); + else c->returnValue()->setHObject(KvsObject_treeWidgetItem::itemToHandle(pItem)); + return true; +} +KVSO_CLASS_FUNCTION(treeWidget,topLevelItemCount) +{ + if (!widget()) return true; + c->returnValue()->setInteger(((QTreeWidget *)widget())->topLevelItemCount()); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidget,addColumn) +{ + if (!widget()) return true; + QString szLabel; + kvs_int_t iW; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel) + KVSO_PARAMETER("width",KVS_PT_INT,KVS_PF_OPTIONAL,iW) + KVSO_PARAMETERS_END(c) + int col=((QTreeWidget *)widget())->columnCount(); + QTreeWidgetItem *header=((QTreeWidget *)widget())->headerItem(); + header->setText(col,szLabel); + if(iW) ((QTreeWidget *)widget())->setColumnWidth(col,iW); + col++; + ((QTreeWidget *)widget())->setColumnCount(col); + //col++; + return true; +} + +KVSO_CLASS_FUNCTION(treeWidget,setAcceptDrops) +{ + bool bEnable; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnable",KVS_PT_BOOLEAN,0,bEnable) + KVSO_PARAMETERS_END(c) + if (widget()) + ((QTreeWidget *)object())->setAcceptDrops(bEnable); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidget,clear) +{ + Q_UNUSED(c); + if (widget()) + ((QTreeWidget *)object())->clear(); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidget,selectedItems) +{ + if(widget()) + { + QList list=((QTreeWidget *)widget())->selectedItems(); + KviKvsArray * pArray = new KviKvsArray(); + c->returnValue()->setArray(pArray); + for (int i=0;iset(i,new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle((QTreeWidgetItem*)list.at(i)))); + } + else + c->returnValue()->setHObject((kvs_hobject_t)0); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidget,firstChild) +{ + if(widget()) + c->returnValue()->setHObject(KvsObject_treeWidgetItem::itemToHandle((QTreeWidgetItem*)((QTreeWidget *)widget())->topLevelItem(0))); + else + c->returnValue()->setHObject((kvs_hobject_t)0); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidget,currentItem) +{ + if(widget()) + c->returnValue()->setHObject(KvsObject_treeWidgetItem::itemToHandle((QTreeWidgetItem*)((QTreeWidget *)widget())->currentItem())); + else + c->returnValue()->setHObject((kvs_hobject_t)0); + return true; +} +/* +KVSO_CLASS_FUNCTION(treeWidget,setColumnText) +{ + kvs_int_t uCol; + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETERS_END(c) + if (widget())((QTreeWidget *)widget())->setColumnText(uCol,szText); + return true; +} +*/ +KVSO_CLASS_FUNCTION(treeWidget,setColumnCount) +{ + kvs_uint_t uCol; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETERS_END(c) + if (widget())((QTreeWidget *)widget())->setColumnCount(uCol); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidget,setSelectionMode) +{ + QString szMode; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("mode",KVS_PT_NONEMPTYSTRING,0,szMode) + KVSO_PARAMETERS_END(c) + if(!widget())return true; + if(KviQString::equalCI(szMode,"NoSelection")) + ((QTreeWidget *)widget())->setSelectionMode(QAbstractItemView::NoSelection); + else if(KviQString::equalCI(szMode,"Multi")) + ((QTreeWidget *)widget())->setSelectionMode(QTreeWidget::MultiSelection); + else if(KviQString::equalCI(szMode,"Extended")) + ((QTreeWidget *)widget())->setSelectionMode(QTreeWidget::ExtendedSelection); + else if(KviQString::equalCI(szMode,"Single")) + ((QTreeWidget *)widget())->setSelectionMode(QTreeWidget::SingleSelection); + else c->warning(__tr2qs_ctx("Invalid selection mode '%Q'","objects"),&szMode); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidget,setSorting) +{ + kvs_int_t iCol; + QString szOrder; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("column",KVS_PT_INT,0,iCol) + KVSO_PARAMETER("sort_order",KVS_PT_STRING,0,szOrder) + KVSO_PARAMETERS_END(c) + if (!widget())return true; + if (KviQString::equalCI(szOrder,"ascending")) ((QTreeWidget *)widget())->sortItems(iCol,Qt::AscendingOrder); + else if (KviQString::equalCI(szOrder,"descending")) ((QTreeWidget *)widget())->sortItems(iCol,Qt::DescendingOrder); + else c->warning(__tr2qs_ctx("Unknown '%Q' sort order: switching to ascending order","objects"),&szOrder); + return true; +} +KVSO_CLASS_FUNCTION(treeWidget,setSortingEnabled) +{ + bool bEnables; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnables",KVS_PT_BOOLEAN,0,bEnables) + KVSO_PARAMETERS_END(c) + if (!widget())return true; + ((QTreeWidget *)widget())->setSortingEnabled(bEnables); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidget,setRootIsDecorated) +{ + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + if (widget()) ((QTreeWidget *)widget())->setRootIsDecorated(bEnabled); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidget,setAllColumnsShowFocus) +{ + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bAllColumnsShowFocus",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + if (widget())((QTreeWidget *)widget())->setAllColumnsShowFocus(bEnabled); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidget,hideListViewHeader) +{ + Q_UNUSED(c); + ((QTreeWidget *)widget())->header()->hide(); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidget,showListViewHeader) +{ + Q_UNUSED(c); + ((QTreeWidget *)widget())->header()->show(); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidget,listViewHeaderIsVisible) +{ + c->returnValue()->setBoolean(((QTreeWidget *)widget())->header()->isVisible()); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidget,itemClickedEvent) +{ + emitSignal("itemClicked",c,c->params()); + return true; +} + +void KvsObject_treeWidget::slotClicked(QTreeWidgetItem * i,int col) +{ + KviKvsVariant *column=new KviKvsVariant((kvs_int_t)col); + + KviKvsVariantList params(new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(i)),column); + callFunction(this,"itemClickedEvent",0,¶ms); +} + +KVSO_CLASS_FUNCTION(treeWidget,selectionChangedEvent) +{ + emitSignal("selectionChanged",c,c->params()); + return true; +} + +void KvsObject_treeWidget::slotSelectionChanged() +{ + if (((QTreeWidget *)widget())->selectionMode()==QTreeWidget::SingleSelection) + { + QTreeWidgetItem *it=(QTreeWidgetItem *) ((QTreeWidget *)widget())->currentItem(); + KviKvsVariantList params(new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(it))); + callFunction(this,"selectionChangedEvent",0,¶ms); + } + else{ + KviKvsVariantList params(new KviKvsVariant((kvs_hobject_t)0)); + callFunction(this,"selectionChangedEvent",0,¶ms); + } +} + +KVSO_CLASS_FUNCTION(treeWidget,currentChangedEvent) +{ + emitSignal("currentChanged",c,c->params()); + return true; +} + +void KvsObject_treeWidget::slotCurrentChanged(QTreeWidgetItem * i,QTreeWidgetItem *prev) +{ + KviKvsVariantList params(new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(i)),new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(prev))); + callFunction(this,"currentChangedEvent",0,¶ms); +} + +KVSO_CLASS_FUNCTION(treeWidget,itemActivatedEvent) +{ + emitSignal("itemActivated",c,c->params()); + return true; +} + +void KvsObject_treeWidget::slotItemActivated(QTreeWidgetItem * i,int col) +{ + KviKvsVariant *column=new KviKvsVariant((kvs_int_t)col); + KviKvsVariantList params(new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(i)),column); + callFunction(this,"itemActivatedEvent",0,¶ms); +} + +KVSO_CLASS_FUNCTION(treeWidget,onItemEvent) +{ + + emitSignal("onItem",c,c->params()); + return true; +} + +void KvsObject_treeWidget::slotOnItemEntered(QTreeWidgetItem * i,int col) +{ + KviKvsVariant *column=new KviKvsVariant((kvs_int_t)col); + + KviKvsVariantList params(new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(i)),column); + callFunction(this,"onItemEvent",0,¶ms); +} + +KVSO_CLASS_FUNCTION(treeWidget,itemExpandedEvent) +{ + emitSignal("itemExpanded",c,c->params()); + return true; +} + +void KvsObject_treeWidget::slotItemExpanded(QTreeWidgetItem * i) +{ + KviKvsVariantList params(new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(i))); + callFunction(this,"itemExpandedEvent",0,¶ms); +} + +KVSO_CLASS_FUNCTION(treeWidget,itemCollapsedEvent) +{ + emitSignal("itemCollapsed",c,c->params()); + return true; +} + +void KvsObject_treeWidget::slotItemCollapsed(QTreeWidgetItem * i) +{ + KviKvsVariantList params(new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(i))); + callFunction(this,"itemCollapsedEvent",0,¶ms); +} + + + +KVSO_CLASS_FUNCTION(treeWidget,itemChangedEvent) +{ + emitSignal("itemChanged",c,c->params()); + return true; +} + +void KvsObject_treeWidget::slotItemChanged(QTreeWidgetItem *item,int col) +{ + KviKvsVariant *column=new KviKvsVariant((kvs_int_t)col); + KviKvsVariantList params(new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(item)),column); + callFunction(this,"itemChangedEvent",0,¶ms); +} + +void KvsObject_treeWidget::fileDropped(QString &szFile,QTreeWidgetItem *item) +{ + KviKvsVariant *file=new KviKvsVariant(szFile); + KviKvsVariantList params(new KviKvsVariant(KvsObject_treeWidgetItem::itemToHandle(item)),file); + callFunction(this,"fileDroppedEvent",0,¶ms); +} + +KviKvsTreeWidget::KviKvsTreeWidget(QWidget * par,const char *,KvsObject_treeWidget *parent) +:QTreeWidget(par) +{ + m_pParentScript=parent; + setAcceptDrops(true); + setDragEnabled(true); + setDropIndicatorShown(true); + setDragDropMode(QAbstractItemView::DragDrop); + viewport()->setAcceptDrops(true); +} + +KviKvsTreeWidget::~KviKvsTreeWidget() +{ +} + +void KviKvsTreeWidget::dragEnterEvent( QDragEnterEvent * e ) +{ + if(!e->mimeData()->hasUrls()) + { + e->ignore(); + return; + } + e->acceptProposedAction(); +} + +void KviKvsTreeWidget::dragMoveEvent( QDragMoveEvent * ) +{ + // ?#! +} + +void KviKvsTreeWidget::dropEvent(QDropEvent * e) +{ + qDebug("Drop event"); + QList list; + if(e->mimeData()->hasUrls()) + { + list = e->mimeData()->urls(); + + if(!list.isEmpty()) + { + QList::Iterator it = list.begin(); + for( ; it != list.end(); ++it ) + { + QUrl url = *it; + QString path = url.toLocalFile(); + qDebug("path %s",path.toUtf8().data()); + QTreeWidgetItem *i = itemAt( e->pos() ); + m_pParentScript->fileDropped(path,i); + } + } + } +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "m_KvsObject_treeWidget.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/objects/KvsObject_treeWidget.h b/src/modules/objects/KvsObject_treeWidget.h new file mode 100644 index 000000000..05fb3f4cc --- /dev/null +++ b/src/modules/objects/KvsObject_treeWidget.h @@ -0,0 +1,100 @@ +#ifndef _CLASS_TREEWIDGET_H_ +#define _CLASS_TREEWIDGET_H_ +//============================================================================= +// +// File : KvsObject_treeWidget.h +// Creation date : Fri Jan 28 14:21:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_widget.h" +#include "KvsObject_treeWidgeteItem.h" +#include "object_macros.h" + +#include + +class KvsObject_treeWidget : public KvsObject_widget +{ + Q_OBJECT +public: + KVSO_DECLARE_OBJECT(KvsObject_treeWidget) + +public: + QWidget * widget() { return (QWidget *)object(); }; + void fileDropped(QString &,QTreeWidgetItem *); +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + + bool addColumn(KviKvsObjectFunctionCall *c); + bool setColumnText(KviKvsObjectFunctionCall *c); + bool takeItem(KviKvsObjectFunctionCall *c); + bool setSorting(KviKvsObjectFunctionCall *c); + bool setSortingEnabled(KviKvsObjectFunctionCall *c); + bool setRootIsDecorated(KviKvsObjectFunctionCall *c); + bool clear(KviKvsObjectFunctionCall *c); + bool setAllColumnsShowFocus(KviKvsObjectFunctionCall *c); + bool itemClickedEvent(KviKvsObjectFunctionCall *c); + bool selectionChangedEvent(KviKvsObjectFunctionCall *c); + bool currentChangedEvent(KviKvsObjectFunctionCall *c); + bool itemActivatedEvent(KviKvsObjectFunctionCall *c); + bool onItemEvent(KviKvsObjectFunctionCall *c); + bool itemExpandedEvent(KviKvsObjectFunctionCall *c); + bool itemCollapsedEvent(KviKvsObjectFunctionCall *c); + bool itemChangedEvent(KviKvsObjectFunctionCall *c); + bool selectedItems(KviKvsObjectFunctionCall *c); + bool currentItem(KviKvsObjectFunctionCall *c); + bool setSelectionMode(KviKvsObjectFunctionCall *c); + bool firstChild(KviKvsObjectFunctionCall *c); + bool listViewHeaderIsVisible(KviKvsObjectFunctionCall *c); + bool showListViewHeader(KviKvsObjectFunctionCall *c); + bool hideListViewHeader(KviKvsObjectFunctionCall *c); + bool setAcceptDrops(KviKvsObjectFunctionCall *c); + bool setHeaderLabels(KviKvsObjectFunctionCall *c); + bool setColumnCount(KviKvsObjectFunctionCall *c); + bool topLevelItem(KviKvsObjectFunctionCall *c); + bool topLevelItemCount(KviKvsObjectFunctionCall *c); + bool itemAt(KviKvsObjectFunctionCall *c); +protected slots: + void slotClicked(QTreeWidgetItem *,int); + void slotSelectionChanged(); + void slotCurrentChanged(QTreeWidgetItem *,QTreeWidgetItem *); + void slotItemActivated(QTreeWidgetItem *,int col); + void slotOnItemEntered(QTreeWidgetItem *,int col); + void slotItemExpanded(QTreeWidgetItem *); + void slotItemCollapsed(QTreeWidgetItem *); + void slotItemChanged(QTreeWidgetItem *,int); +}; + +class KviKvsTreeWidget : public QTreeWidget +{ + Q_OBJECT +public: + KviKvsTreeWidget(QWidget * par, const char * name, KvsObject_treeWidget *); + virtual ~KviKvsTreeWidget(); +protected: + KvsObject_treeWidget * m_pParentScript; +protected: + void dropEvent(QDropEvent * e); + void dragEnterEvent(QDragEnterEvent * e); + void dragMoveEvent( QDragMoveEvent * e ); +}; + +#endif // _CLASS_TREEWIDGET_H_ diff --git a/src/modules/objects/KvsObject_treeWidgeteItem.cpp b/src/modules/objects/KvsObject_treeWidgeteItem.cpp new file mode 100644 index 000000000..da7422687 --- /dev/null +++ b/src/modules/objects/KvsObject_treeWidgeteItem.cpp @@ -0,0 +1,429 @@ +//============================================================================= +// +// File : KvsObject_treeWidgeteItem.cpp +// Creation date : Fri Jan 28 14:21:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_treeWidgeteItem.h" +#include "KvsObject_pixmap.h" + +#include "KviError.h" +#include "kvi_debug.h" +#include "KviLocale.h" +#include "KviIconManager.h" +#include + +const int item_flags[] = { + Qt::NoItemFlags, + Qt::ItemIsSelectable, + Qt::ItemIsEditable, + Qt::ItemIsDragEnabled, + Qt::ItemIsDropEnabled, + Qt::ItemIsUserCheckable, + Qt::ItemIsEnabled, + Qt::ItemIsTristate +}; + +const char * const itemflags_tbl[] = { + "noitemflag", + "selectable", + "editable", + "dragEnabled", + "dropEnabled", + "userCheckable", + "enabled", + "tristate" +}; + +#define itemflags_num (sizeof(itemflags_tbl) / sizeof(itemflags_tbl[0])) + + + +/* + @doc: listviewitem + @keyterms: + listview tlistviewitem class + @title: + listviewtitem class + @type: + class + @short: + A listviewitem class + @inherits: + [class]listviewitem[/class] + @description: + The listviewitem class implements a list view item. + A list view item is a multi-column object capable of displaying itself in a [class]listview[/class]. + To use this class you must instantiate it with another listviewitem or a [class]listview[/class] + as parent. The item will be automatically displayed. + You can set the text and a pixmap in each column and you can make it checkable + with [classfnc:listviewitem]$setCheckable[/classfnc](). + A checkable listviewitem will display a small check mark in the first column. + @functions: + !fn: $setText(,) + Sets the text in column column to text, if column is a valid column number and text is different from the existing text. + + !fn: $text() + Returs the text of the specified column. + + !fn: $setPixmap(,) + Sets the pixmap in column column to pm, if pm is non-null and different from the current pixmap, and if column is non-negative. + Pixmap can be a Kvirc imageid, an image file or a [class]pixmap[/class] object. + + !fn: $setItemEditable() + If bEnabled is TRUE (1), this item can be in-place editable by the user; otherwise it cannot be editable in-place. + + !fn: $isItemEditable() + Returns $true if this item is editable and $false otherwise. + + !fn: $setEnabled() + Enables or disables the item. + + !fn: $isEnabled() + Returns $true if this item is enabled and $false otherwise. + + !fn: $setOpen() + Opens or closes the item to show its children items. + + !fn: $isOpen() + Returns the open state of this item + + !fn: $setCheckable() + Makes this item checkable or not. This function should be called immediately + after the item creation: changing this property later at runtime may have + strange results (like the item being moved inside the list, text disappearing, + hidden children etc... don't do it :D ). + + !fn: $isCheckable() + Returns $true if this item is checkable and $false otherwise + + !fn: $setChecked() + Sets this item to be checked or not. [classfnc:listviewitem]$setCheckable[/classfnc]() must + have been previously called. + + !fn: $isChecked() + Returns the check status of this item. [classfnc:listviewitem]$setCheckable[/classfnc]() must + have been previously called. + + !fn: $setFlags(, , ...) + Sets the flags for the item to the given flags. These determine whether the item can be selected or modified. This is often used to disable an item. + Supported flags are: + - noitemflag : no flag sets; + - selectable : item is selecatble; + - editable : item is editable; + - dragEnabled : item can dragged; + - dropEnabled : item can used as drop target; + - userCheckable : item is checkable; + - enabled :item is enabled; + - tristate : item is checkable with three separate states. + + +*/ + + +//=========================================================================================== + +KVSO_BEGIN_REGISTERCLASS(KvsObject_treeWidgetItem,"listviewitem","object") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidgetItem,setText) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidgetItem,text) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidgetItem,setPixmap); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidgetItem,setItemEditable); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidgetItem,isItemEditable); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidgetItem,setEnabled); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidgetItem,isEnabled); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidgetItem,setOpen); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidgetItem,isOpen); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidgetItem,setCheckable); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidgetItem,isCheckable); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidgetItem,setChecked); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidgetItem,isChecked); + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_treeWidgetItem,setFlags); + +KVSO_END_REGISTERCLASS(KvsObject_treeWidgetItem) + + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_treeWidgetItem,KviKvsObject) + + m_pTreeWidgetItem = 0; + +KVSO_END_CONSTRUCTOR(KvsObject_treeWidgetItem) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_treeWidgetItem) + + if(m_pTreeWidgetItem)delete m_pTreeWidgetItem; + +KVSO_END_CONSTRUCTOR(KvsObject_treeWidgetItem) + +bool KvsObject_treeWidgetItem::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *) +{ + if (!parentObject()) + { + pContext->error(__tr2qs_ctx("The listviewitem cannot be parentless","objects")); + return false; + } + if(parentObject()->inheritsClass("listviewitem")) + { + m_pTreeWidgetItem = new KviKvsStandardTreeWidgetItem(this,((KvsObject_treeWidgetItem *)parentObject())->m_pTreeWidgetItem); + } else { + if(parentObject()->inheritsClass("listview")) + m_pTreeWidgetItem = new KviKvsStandardTreeWidgetItem(this,((QTreeWidget *)parentScriptWidget())); + else { + pContext->error(__tr2qs_ctx("The parent of the listviewitem must be either another listviewitem or a listview","objects")); + return false; + } + } + return true; +} + +void KvsObject_treeWidgetItem::childDestroyed() +{ + if(m_pTreeWidgetItem == 0)return; + m_pTreeWidgetItem = 0; + die(); +} + +KviKvsStandardTreeWidgetItem::KviKvsStandardTreeWidgetItem(KvsObject_treeWidgetItem * ob,QTreeWidget * par) +:QTreeWidgetItem(par), m_pMasterObject(ob) +{ +} + +KviKvsStandardTreeWidgetItem::KviKvsStandardTreeWidgetItem(KvsObject_treeWidgetItem * ob,QTreeWidgetItem * par) +:QTreeWidgetItem(par), m_pMasterObject(ob) +{ +} + +KviKvsStandardTreeWidgetItem::~KviKvsStandardTreeWidgetItem() +{ + if(m_pMasterObject)m_pMasterObject->childDestroyed(); +} + +kvs_hobject_t KvsObject_treeWidgetItem::itemToHandle(QTreeWidgetItem * it) +{ + if(!it)return (kvs_hobject_t)0; + KvsObject_treeWidgetItem * pObject; + pObject = ((KviKvsStandardTreeWidgetItem *)it)->masterObject(); + if(!pObject)return (kvs_hobject_t)0; + return pObject->handle(); +} + +KVSO_CLASS_FUNCTION(treeWidgetItem,setText) +{ + kvs_uint_t uCol; + QString szText; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) + KVSO_PARAMETERS_END(c) + if(m_pTreeWidgetItem) + m_pTreeWidgetItem->setText(uCol,szText); + return true; +} + + +KVSO_CLASS_FUNCTION(treeWidgetItem,setItemEditable) +{ + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + if(m_pTreeWidgetItem) + m_pTreeWidgetItem->setFlags(bEnabled?m_pTreeWidgetItem->flags()|Qt::ItemIsEditable:m_pTreeWidgetItem->flags()&~Qt::ItemIsEditable); + return true; +} +KVSO_CLASS_FUNCTION(treeWidgetItem,isItemEditable) +{ + if(!m_pTreeWidgetItem) + { + c->returnValue()->setBoolean(false); + return true; + } + c->returnValue()->setBoolean(m_pTreeWidgetItem->flags()&Qt::ItemIsEditable); + return true; +} +KVSO_CLASS_FUNCTION(treeWidgetItem,setFlags) +{ + QStringList itemflags; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("flags",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,itemflags) + KVSO_PARAMETERS_END(c) + int flag,sum=0; + for ( int i=0;isetCheckState(0,Qt::Unchecked); + sum = sum | flag; + } + else + c->warning(__tr2qs_ctx("Unknown item flag '%Q'","objects"),&itemflags.at(i)); + } + if(m_pTreeWidgetItem) + m_pTreeWidgetItem->setFlags((Qt::ItemFlags)sum); + + return true; +} + +KVSO_CLASS_FUNCTION(treeWidgetItem,setEnabled) +{ + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + if(m_pTreeWidgetItem) + m_pTreeWidgetItem->setFlags(bEnabled?m_pTreeWidgetItem->flags()|Qt::ItemIsEnabled:m_pTreeWidgetItem->flags()&~Qt::ItemIsEnabled); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidgetItem,isEnabled) +{ + if(!m_pTreeWidgetItem) + { + c->returnValue()->setBoolean(false); + return true; + } + c->returnValue()->setBoolean(m_pTreeWidgetItem->flags()&Qt::ItemIsEnabled); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidgetItem,setOpen) +{ + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + if(m_pTreeWidgetItem) + m_pTreeWidgetItem->setExpanded(bEnabled); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidgetItem,isOpen) +{ + if(!m_pTreeWidgetItem) + { + c->returnValue()->setBoolean(false); + return true; + } + c->returnValue()->setBoolean(m_pTreeWidgetItem->isExpanded()); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidgetItem,setChecked) +{ + bool bChecked; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bChecked",KVS_PT_BOOL,0,bChecked) + KVSO_PARAMETERS_END(c) + if(!m_pTreeWidgetItem)return true; + ((QTreeWidgetItem *)m_pTreeWidgetItem)->setCheckState(0,bChecked?Qt::Checked:Qt::Unchecked); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidgetItem,isChecked) +{ + if(!m_pTreeWidgetItem) + { + c->returnValue()->setBoolean(false); + return true; + } + c->returnValue()->setBoolean(((QTreeWidgetItem *)m_pTreeWidgetItem)->checkState(0)==Qt::Checked?1:0); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidgetItem,setCheckable) +{ + bool bEnabled; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bCheckable",KVS_PT_BOOL,0,bEnabled) + KVSO_PARAMETERS_END(c) + if(!m_pTreeWidgetItem)return true; + m_pTreeWidgetItem->setFlags(bEnabled?m_pTreeWidgetItem->flags()|Qt::ItemIsUserCheckable:m_pTreeWidgetItem->flags()&~Qt::ItemIsUserCheckable); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidgetItem,isCheckable) +{ + if(!m_pTreeWidgetItem) + { + c->returnValue()->setBoolean(false); + return true; + } + c->returnValue()->setBoolean(m_pTreeWidgetItem->flags()&Qt::ItemIsUserCheckable); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidgetItem,text) +{ + kvs_uint_t uCol; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETERS_END(c) + if(m_pTreeWidgetItem) + c->returnValue()->setString(m_pTreeWidgetItem->text(uCol)); + return true; +} + +KVSO_CLASS_FUNCTION(treeWidgetItem,setPixmap) +{ + kvs_uint_t uCol; + KviKvsObject *obPixmap; + kvs_hobject_t obHpixmap; + KviKvsVariant * vPixmap; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETER("pixmap",KVS_PT_VARIANT,0,vPixmap) + KVSO_PARAMETERS_END(c) + QPixmap *pix = 0; + if (vPixmap->isEmpty()) {m_pTreeWidgetItem->setIcon(uCol,QIcon());return true;} + if(vPixmap->isHObject()) + { + vPixmap->asHObject(obHpixmap); + obPixmap=KviKvsKernel::instance()->objectController()->lookupObject(obHpixmap); + if (!obPixmap->inheritsClass("pixmap")) + { + c->warning(__tr2qs_ctx("Pixmap object or image Id required","objects")); + return true; + } + pix=((KvsObject_pixmap *)obPixmap)->getPixmap(); + } else { + QString szPix; + vPixmap->asString(szPix); + pix=g_pIconManager->getImage(szPix); + if(!pix) + { + c->warning(__tr2qs_ctx("Error occured: the suitable file '%Q' is not of the correct format or it is not a valid icon number.","objects"),&szPix); + return true; + } + } + m_pTreeWidgetItem->setIcon(uCol,QIcon(*pix)); + return true; +} + diff --git a/src/modules/objects/KvsObject_treeWidgeteItem.h b/src/modules/objects/KvsObject_treeWidgeteItem.h new file mode 100644 index 000000000..d2c56b8c6 --- /dev/null +++ b/src/modules/objects/KvsObject_treeWidgeteItem.h @@ -0,0 +1,78 @@ +#ifndef _CLASS_TREEWIDGETITEM_H_ +#define _CLASS_TREEWIDGETITEM_H_ +//============================================================================= +// +// File : KvsObject_treeWidgeteItem.h +// Creation date : Fri Jan 28 14:21:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + + +#include "KvsObject_widget.h" +#include "object_macros.h" + +#include + +class KvsObject_treeWidgetItem : public KviKvsObject +{ +public: + KVSO_DECLARE_OBJECT(KvsObject_treeWidgetItem) + void childDestroyed(); +protected: + QTreeWidgetItem * m_pTreeWidgetItem; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); +protected: + bool setText(KviKvsObjectFunctionCall *c); + bool insertItem(KviKvsObjectFunctionCall *c); + bool setPixmap(KviKvsObjectFunctionCall *c); + bool setItemEditable(KviKvsObjectFunctionCall *c); + bool isItemEditable(KviKvsObjectFunctionCall *c); + bool setEnabled(KviKvsObjectFunctionCall *c); + bool isEnabled(KviKvsObjectFunctionCall *c); + bool setOpen(KviKvsObjectFunctionCall *c); + bool isOpen(KviKvsObjectFunctionCall *c); + bool text(KviKvsObjectFunctionCall *c); + bool setCheckable(KviKvsObjectFunctionCall *c); + bool isCheckable(KviKvsObjectFunctionCall *c); + bool setChecked(KviKvsObjectFunctionCall *c); + bool isChecked(KviKvsObjectFunctionCall *c); + bool setFlags(KviKvsObjectFunctionCall *c); + +public: + static kvs_hobject_t itemToHandle(QTreeWidgetItem * it); +}; + + +class KviKvsStandardTreeWidgetItem : public QTreeWidgetItem +{ +public: + KviKvsStandardTreeWidgetItem(KvsObject_treeWidgetItem * ob,QTreeWidget * par); + KviKvsStandardTreeWidgetItem(KvsObject_treeWidgetItem * ob,QTreeWidgetItem * par); + virtual ~KviKvsStandardTreeWidgetItem(); +protected: + KvsObject_treeWidgetItem * m_pMasterObject; +public: + KvsObject_treeWidgetItem * masterObject(){ return m_pMasterObject; } +}; + + +#endif // _CLASS_TREEWIDGETITEM_H_ diff --git a/src/modules/objects/KvsObject_vBox.cpp b/src/modules/objects/KvsObject_vBox.cpp new file mode 100644 index 000000000..65fced903 --- /dev/null +++ b/src/modules/objects/KvsObject_vBox.cpp @@ -0,0 +1,209 @@ +//============================================================================= +// +// File : KvsObject_vBox.cpp +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#define _KVI_DEBUG_CHECK_RANGE_ +#include "kvi_debug.h" +#include "KviLocale.h" + +#include "KvsObject_vBox.h" + +#include "KviTalVBox.h" + + +// Tables used in $setAlignment & $alignment +const char * const align_tbl[] = { + "Left", + "Right", + "HCenter", + "VCenter", + "Center", + "Top", + "Bottom", + "WordBreak" + }; + + + +const int align_cod[] = { + Qt::AlignLeft, + Qt::AlignRight, + Qt::AlignHCenter, + Qt::AlignVCenter, + Qt::AlignCenter, + Qt::AlignTop, + Qt::AlignBottom, + Qt::AlignJustify, + }; + +#define align_num (sizeof(align_tbl) / sizeof(align_tbl[0])) +/* + @doc: vbox + @keyterms: + vbox object class, child widgets + @title: + vbox class + @type: + class + @short: + Manages child widget vertical geometry + @inherits: + [class]object[/class] + @description: + The vbox class widget provides vertical geometry management for its child widgets. + @functions: + !fn: $setSpacing() + Sets the default spacing of the widgets in pixels + !fn: $setMargin() + Sets the dimension of the layout margin : the distance from the border to the outermost child widget edges. + !fn: $setStretchFactor(,) + Sets the stretch factor of widget to stretch. + !fn: $addStretch() + Adds a stretchable space with zero minimum size and stretch factor stretch to the end of this box layout. + !fn: $setAlignment(, , ...) + Sets the alignment for widget w to flags, given as parameters. + Valid flags are:Right,Left,Top,Bottom,HCenter,VCenter,Center +*/ + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_vBox,"vbox","widget") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_vBox,setMargin) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_vBox,setSpacing) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_vBox,setStretchFactor) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_vBox,addStretch) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_vBox,setAlignment) +KVSO_END_REGISTERCLASS(KvsObject_vBox) + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_vBox,KvsObject_widget) + +KVSO_END_CONSTRUCTOR(KvsObject_vBox) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_vBox) + +KVSO_END_CONSTRUCTOR(KvsObject_vBox) + +bool KvsObject_vBox::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams) +{ + Q_UNUSED(pContext); + Q_UNUSED(pParams); + + SET_OBJECT(KviTalVBox); + return true; +} + +KVSO_CLASS_FUNCTION(vBox,setMargin) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iMargin; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("margin",KVS_PT_INT,0,iMargin) + KVSO_PARAMETERS_END(c) + ((KviTalVBox *)widget())->setMargin(iMargin); + return true; +} + +KVSO_CLASS_FUNCTION(vBox,setSpacing) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iSpacing; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("spacing",KVS_PT_INT,0,iSpacing) + KVSO_PARAMETERS_END(c) + ((KviTalVBox *)widget())->setSpacing(iSpacing); + return true; +} + +KVSO_CLASS_FUNCTION(vBox,setStretchFactor) +{ + CHECK_INTERNAL_POINTER(widget()) + KviKvsObject * pObject; + kvs_hobject_t hObject; + kvs_uint_t uStretch; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETER("stretch",KVS_PT_UNSIGNEDINTEGER,0,uStretch) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + return true; + CHECK_HOBJECT_IS_WIDGET(pObject) + if(((KvsObject_widget *)pObject)->widget()->parentWidget() != widget()) + { + c->warning(__tr2qs_ctx("The widget must be a child of this vbox","objects")); + return true; + } + ((KviTalVBox *)widget())->setStretchFactor(((QWidget *)(pObject->object())),uStretch); + return true; +} +KVSO_CLASS_FUNCTION(vBox,addStretch) +{ + CHECK_INTERNAL_POINTER(widget()) + kvs_int_t iStretch; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("stretch",KVS_PT_INT,0,iStretch) + KVSO_PARAMETERS_END(c) + ((KviTalVBox *)widget())->addStretch(iStretch); + return true; +} +KVSO_CLASS_FUNCTION(vBox,setAlignment) +{ + CHECK_INTERNAL_POINTER(widget()) + QStringList alignment; + KviKvsObject * pObject; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETER("alignment",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,alignment) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + CHECK_HOBJECT_IS_WIDGET(pObject) + if(((KvsObject_widget *)pObject)->widget()->parentWidget() != widget()) + { + c->warning(__tr2qs_ctx("The widget must be a child of this hbox","objects")); + return true; + } + + int align,sum=0; + for ( QStringList::Iterator it = alignment.begin(); it != alignment.end(); ++it ) + { + + align = 0; + for(unsigned int j = 0; j < align_num; j++) + { + if(KviQString::equalCI((*it), align_tbl[j])) + { + align=align_cod[j]; + break; + } + } + if(align) + sum = sum | align; + else + c->warning(__tr2qs_ctx("Unknown alignment: '%Q'","objects"),&(*it)); + + } + if (widget()) ((KviTalHBox *)widget())->setAlignment(((QWidget *)(pObject->object())),(Qt::Alignment)sum); + return true; +} + diff --git a/src/modules/objects/KvsObject_vBox.h b/src/modules/objects/KvsObject_vBox.h new file mode 100644 index 000000000..08342bea2 --- /dev/null +++ b/src/modules/objects/KvsObject_vBox.h @@ -0,0 +1,49 @@ +#ifndef _CLASS_VBOX_H_ +#define _CLASS_VBOX_H_ +//============================================================================= +// +// File : KvsObject_vBox.h +// Creation date : Fri Mar 18 14:30:48 CEST 2005 +// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KviCString.h" +#include "KvsObject_widget.h" +#include "object_macros.h" + +class KvsObject_vBox : public KvsObject_widget +{ +public: + KVSO_DECLARE_OBJECT(KvsObject_vBox) +public: + QWidget * widget() { return (QWidget *)object(); }; +protected: + virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); + bool setMargin(KviKvsObjectFunctionCall *c); + bool setSpacing(KviKvsObjectFunctionCall *c); + bool setStretchFactor(KviKvsObjectFunctionCall *c); + bool addStretch(KviKvsObjectFunctionCall *c); + bool setAlignment(KviKvsObjectFunctionCall *c); + +}; + + +#endif //_CLASS_HBOX_H_ diff --git a/src/modules/objects/KvsObject_widget.cpp b/src/modules/objects/KvsObject_widget.cpp new file mode 100644 index 000000000..c0598b7ae --- /dev/null +++ b/src/modules/objects/KvsObject_widget.cpp @@ -0,0 +1,2030 @@ +//============================================================================= +// +// File : KvsObject_widget.cpp +// Creation date : Mon Sep 11 16:35:32 CET 2000 by Krzysztof Godlewski +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000 Krzysztof Godlewski +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// 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 opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "KvsObject_widget.h" +#include "KvsObject_pixmap.h" + +#include "KviMemory.h" +#include "kvi_debug.h" +#include "KviError.h" +#include "KviLocale.h" +#include "KviIconManager.h" +#include "KviWindow.h" +#include "KviApplication.h" +#include "KviMainWindow.h" +#include "KviStatusBar.h" +#include "KvsObject_painter.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef COMPILE_WEBKIT_SUPPORT + #include +#endif + +KviKvsWidget::KviKvsWidget(KvsObject_widget * object,QWidget * par) +:QWidget(par), m_pObject(object) +{ +} + +KviKvsWidget::~KviKvsWidget() +{ +} + +QSize KviKvsWidget::sizeHint() const +{ + QSize size=QWidget::sizeHint(); + KviKvsVariant *tipret=new KviKvsVariant(); + KviKvsVariantList params(new KviKvsVariant((kvs_int_t)size.width()),new KviKvsVariant((kvs_int_t)size.height())); + m_pObject->callFunction(m_pObject,"sizeHintRequestEvent",tipret,¶ms); + if (tipret->isArray()) + { + if (tipret->array()->size()==2) + { + kvs_int_t w,h; + if (tipret->array()->at(0)->asInteger(w) && tipret->array()->at(1)->asInteger(h))return QSize(w,h); + } + } + return QWidget::sizeHint(); +} + + + +const Qt::WidgetAttribute widgetattributes_cod[] = { + Qt::WA_OpaquePaintEvent, + Qt::WA_NoSystemBackground, + Qt::WA_PaintOnScreen, + Qt::WA_NoMousePropagation +}; + +const char * const widgetattributes_tbl[] = { + "opaquePaintEvent", + "noSystemBackground", + "paintOnScreen", + "noMousePropagation" +}; + +#define widgetattributes_num (sizeof(widgetattributes_tbl) / sizeof(widgetattributes_tbl[0])) + +const QPalette::ColorRole colorrole_cod[] = { + QPalette::Window, + QPalette::Background, + QPalette::WindowText, + QPalette::Foreground, + QPalette::Base, + QPalette::AlternateBase, + QPalette::Text, + QPalette::Button, + QPalette::ButtonText, + QPalette::BrightText, + QPalette::Highlight, + QPalette::HighlightedText +}; + +const char * const colorrole_tbl[] = { + "Window", + "Background", + "WindowText", + "Foreground", + "Base", + "AlternateBase", + "Text", + "Button", + "ButtonText", + "BrightText", + "Highlight", + "HighlightedText" +}; + +#define colorrole_num (sizeof(colorrole_tbl) / sizeof(colorrole_tbl[0])) + + +const Qt::WindowType widgettypes_cod[] = { + Qt::Window, + Qt::Dialog, + Qt::Popup, + Qt::Desktop, + Qt::WindowTitleHint, + Qt::WindowStaysOnTopHint, + Qt::WindowSystemMenuHint, + Qt::WindowMinimizeButtonHint, + Qt::WindowMaximizeButtonHint, + Qt::SubWindow, + Qt::FramelessWindowHint +}; + + +const char * const widgettypes_tbl[] = { + "Window", + "Dialog", + "Popup", + "Desktop", + "Title", + "StaysOnTop", + "SysMenu", + "Minimize", + "Maximize", + "Subwindow", + "FramelessWindow" +}; + + +#define widgettypes_num (sizeof(widgettypes_tbl) / sizeof(widgettypes_tbl[0])) + + +#define QT_WIDGET_TABFOCUS Qt::TabFocus +#define QT_WIDGET_CLICKFOCUS Qt::ClickFocus +#define QT_WIDGET_STRONGFOCUS Qt::StrongFocus +#define QT_WIDGET_NOFOCUS Qt::NoFocus +/* + @doc: widget + @keyterms: + widget object class + @title: + widget class + @type: + class + @short: + Base class for all widgets + @inherits: + [class]object[/class] + @description: + This object class is the rappresentation of a widget. + All the other widget-type classes inherit from this one. + @functions: + !fn: $show() + Shows this widget and the children. + See also [classfnc]$hide[/classfnc]() and [classfnc]$isVisible[/classfnc]. + !fn: $hide() + Hides this widget (and conseguently all the children). + See also [classfnc]$show[/classfnc]() and [classfnc]$isVisible[/classfnc]. + !fn: $repaint() + Repaints the widget directly by calling [classfnc]$paintEvent[/classfnc]() immediately. + !fn: $update([,,,]) + Updates enterily the widget or a rectangle. + This function does not cause an immediate [classfnc]$paintEvent[/classfnc](); instead it schedules a paint event for processing when KVIrc returns to the main event loop. + !fn: $x() + Returns the x coordinate of the upper-left corner + of this widget relative to the parent widget, + or to the desktop if this widget is a toplevel one. + !fn: $y() + Returns the y coordinate of the uspper-left corner + of this widget relative to the parent widget, + or to the desktop if this widget is a toplevel one. + !fn: $width() + Returns the width of this widget in pixels. + !fn: $height() + Returns the height of this widget in pixels. + !fn: $geometry() + Returns the widget geometry in this form:[br] + x, y, width, height. + !fn: $setGeometry(,[,,]) + Sets the geometry of this widget. and are relative + to the parent widget or to the desktop (if this widget is + a toplevel one). All the parameters are in pixels. + !fn: $setMinimumWidth() + Sets the minimum width of this widget to . + The user will not be able to resize the widget to a smaller + value. This value is also used by the [class:layout]layout class[/class]. + !fn: $setMinimumHeight() + Sets the minimum height of this widget to . + The user will not be able to resize the widget to a smaller + value. This value is also used by the [class:layout]layout class[/class]. + !fn: $setMaximumWidth() + Sets the maximum width of this widget to . + The user will not be able to resize the widget to a bigger + value. This value is also used by the [class:layout]layout class[/class]. + !fn: $setMaximumHeight() + Sets the maximum height of this widget to . + The user will not be able to resize the widget to a bigger + value. This value is also used by the [class:layout]layout class[/class]. + !fn: $move([,]) + Moves this widget to the coordinate and relative to its + parent widget (or the desktop if this widget is a toplevel one). + This is equivalent to [classfnc]$setGeometry[/classfnc](,, + [classfnc]$width[/classfnc](),[classfnc]$height[/classfnc]()). + !fn: $resize(,[height]) + Changes the widget's width to and height to . + See also [classfnc]$setGeometry[/classfnc](). + !fn: $isEnabled() + Returns '1' if the widget is enabled, '0' otherwise. + See also [classfnc:widget]$setEnabled[/classfnc](). + !fn: $setEnabled() + Sets the widget state to enabled or disabled if is 1 or 0 respectively. + A disabled widget does not receive keyboard nor mouse input. + !fn: $setWindowTitle() + Sets the title of this widget to . + This is meaningful for toplevel widgets only. + !fn: $setToolTip() + Set the tooltip of this widget; the text can contain HTML formatting. + !fn: $windowTitle() + Returns the title text of this widget. + !fn: $isTopLevel() + Returns '1' if this widget is a toplevel (parentless) one, + '0' otherwise. + !fn: $isVisible() + Returns '1' if this widget is currently visible (read: is managed + by the window manager and displayed by the X server; the widget + may be hidden behind other widgets). If the widget is not visible + this function returns '0'. + See also [classfnc]$show[/classfnc]() and [classfnc]$hide[/classfnc](). + !fn: $raise() + Moves this widget to the top of the stack of the widgets relative + to its parent. See also [classfnc]$lower[/classfnc]. + !fn: $lower() + Moves this widget to the bottom of the stack of the widgets relative + to its parent. See also [classfnc]$raise[/classfnc] + !fn: $hasFocus() + Returns '1' if this widget has the keyboard focus. + See also [classfnc]$setFocus[/classfnc]. + !fn: $setFocus() + Sets this widget to be the one that receives keyboard events. + See also [classfnc]$hasFocus[/classfnc] + !fn: $parentWidget() + Returns the object id of the parent widget, or '0' if this + widget is a toplevel one. + !fn: $backgroundColor() + Returns the background color of this widget in hexadecimal + html-like format. For example, for a black bacground you will get + the string "000000", for a red one, "FF0000", for a white one + "FFFFFF". See also [classfnc]$setBackgroundColor[/classfnc]() + !fn: $setBackgroundColor(,[geen:integer],[blue:integer]) + Sets the background color of this widget to :valid values are: + - hex string: must be a string with 6 hexadecimal digits (like the ones used to + specify colors in html pages). The first two digits specify + the RED component, the third and fourth digit specify the GREEN component + and the last two specify the BLUE component. + For example "FFFF00" means full red, full green and no blue that gives + a yellow color, "808000" designates a brown color (dark yellow), + "A000A0" is a kind of violet. + - array(red:integer,green:integer,blue:integer) + - red:integer,green:integer,blue:integer. + See also [classfnc]$foregroundColor[/classfnc]. + !fn: $setForegroundColor(,[geen:integer],[blue:integer]) + Sets the foreground color of this widget to :valid values are: + - hex string: must be a string with 6 hexadecimal digits (like the ones used to + specify colors in html pages). The first two digits specify + the RED component, the third and fourth digit specify the GREEN component + and the last two specify the BLUE component. + For example "FFFF00" means full red, full green and no blue that gives + a yellow color, "808000" designates a brown color (dark yellow), + "A000A0" is a kind of violet. + - array(red:integer,green:integer,blue:integer) + - red:integer,green:integer,blue:integer. + See also [classfnc]$foregroundColor[/classfnc]. + !fn: $foregroundColor() + Returns the foreground color of this widget in hexadecimal + html-like format. + See also [classfnc]$setForegroundColor[/classfnc]. + !fn: $setMouseTracking() + Enables or disables the mouse tracking if is '1' or '0' respectively. + When mouse tracking is enabled you will receive mouse move events + even if no button is pressed, otherwise you will receive it only + when a mouse button is being pressed (so after a mousePressEvent). + !fn: $mousePressEvent(. - !fn: $showColumn() - Shows the column . - !fn: $clear() - Clears the table. - !fn: $itemEnteredEvent() - This event is triggered when the mouse cursor enters an cell. - !fn: $cellActivatedEvent() - This event is triggered when the cell specified by row and column has been activated - !fn: $cellDoubleClickedEvent() - This event is triggered whenever a cell in the table is double clicked. - !fn: $paintCellEvent(,,,,) - This event handler can be reimplemented to repaint cells. - The framework will pass the row/col coordinates, cell's width and height, and, as parameter, a [class]painter[/class]object. - You don't need to begin/end/delete the painter. - !fn: $sizeHintCellRequestEvent() - This event handler can be reimplemented to pass a custom size hint for this cell to the table layout - !fn; $resizeRowsToContents() - This function will try to redistribute the available space according to the space requirement of each row - !fn; $resizeColumnsToContents() - This function will try to redistribute the available space according to the space requirement of each column - @signals: - !sg: $clicked() - This signal is emitted by the default implementation of [classfnc]$clickEvent[/classfnc](). - -*/ - - -KVSO_BEGIN_REGISTERCLASS(KviKvsObject_tablewidget,"tablewidget","widget") - - // Horizontal Header - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,setHorizontalHeaderLabels) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,hideHorizontalHeader) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,hideVerticalHeader) - - // Vertical Header - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,setVerticalHeaderLabels) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,showHorizontalHeader) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,showVerticalHeader) - - // Rows-Columns - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,setRowCount) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,insertRow) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,insertColumn) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,removeRow) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,removeColumn) - - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,rowCount) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,currentRow) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,setColumnCount) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,columnCount) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,currentColumn) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,itemRowColAt) - - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,hideRow) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,showRow) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,hideColumn) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,showColumn) - - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,resizeRowsToContents) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,resizeColumnsToContents) - - // Item (text. icon, widget) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,setText) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,setNumber) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,setToolTip) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,text) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,setCellWidget) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,setIcon) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,clear) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tablewidget,setItemFlags); - - KVSO_REGISTER_HANDLER(KviKvsObject_tablewidget,"itemEnteredEvent",itemEnteredEvent); - KVSO_REGISTER_HANDLER(KviKvsObject_tablewidget,"cellActivatedEvent",cellActivatedEvent); - KVSO_REGISTER_HANDLER(KviKvsObject_tablewidget,"cellDoubleClickedEvent",cellDoubleClickedEvent); - KVSO_REGISTER_STANDARD_TRUERETURN_HANDLER(KviKvsObject_tablewidget,"paintCellEvent") - KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_tablewidget,"sizeHintCellRequestEvent") - - - -KVSO_END_REGISTERCLASS(KviKvsObject_tablewidget) - -KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_tablewidget,KviKvsObject_widget) - -KVSO_END_CONSTRUCTOR(KviKvsObject_tablewidget) - - -KVSO_BEGIN_DESTRUCTOR(KviKvsObject_tablewidget) -/*if (m_pCellItemDelegate) -{ - delete m_pCellItemDelegate; - m_pCellItemDelegate=0; -}*/ -KVSO_END_DESTRUCTOR(KviKvsObject_tablewidget) - -bool KviKvsObject_tablewidget::init(KviKvsRunTimeContext *c,KviKvsVariantList *) -{ - - SET_OBJECT(QTableWidget) - m_pCellItemDelegate=new KviCellItemDelegate(((QTableWidget *)widget()),this); - - m_pContext=c; - ((QTableWidget *)widget())->setItemDelegate(m_pCellItemDelegate); - ((QTableWidget *)widget())->verticalHeader()->resizeSections(QHeaderView::Custom ); - ((QTableWidget *)widget())->horizontalHeader()->resizeSections(QHeaderView::Custom ); - - connect(widget(),SIGNAL(itemEntered(QTableWidgetItem *)),this,SLOT(slotItemEntered(QTableWidgetItem *))); - connect(widget(),SIGNAL(cellActivated(int,int)),this,SLOT(cellActivated(int,int))); - connect(widget(),SIGNAL(cellDoubleClicked(int,int)),this,SLOT(cellDoubleClicked(int,int))); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,clear) -{ - CHECK_INTERNAL_POINTER(widget()) - ((QTableWidget *)widget())->clear(); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,resizeRowsToContents) -{ - CHECK_INTERNAL_POINTER(widget()) - //qDebug("resize row to contents"); - - ((QTableWidget *)widget())->resizeRowsToContents(); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,resizeColumnsToContents) -{ - CHECK_INTERNAL_POINTER(widget()) - //qDebug("resize coluns to contents"); - ((QTableWidget *)widget())->resizeColumnsToContents(); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,setText) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_uint_t uCol,uRow; - QString szText; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) - KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) - KVSO_PARAMETERS_END(c) - if(uRow >= (uint)((QTableWidget *)widget())->rowCount() || uRow >= (uint)((QTableWidget *)widget())->rowCount()) - c->warning(__tr2qs_ctx("Item out of the tablewidget size","objects")); - QTableWidgetItem * pItem = ((QTableWidget *)widget())->item(uRow,uCol); - if(!pItem) - { - pItem = new QTableWidgetItem(); - ((QTableWidget *)widget())->setItem(uRow,uCol,pItem); - } - pItem->setText(szText); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,setNumber) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_uint_t uCol,uRow; - kvs_int_t iNumber; - QString szText; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) - KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETER("number",KVS_PT_INT,0,iNumber) - KVSO_PARAMETERS_END(c) - if(uRow >= (uint)((QTableWidget *)widget())->rowCount() || uRow >= (uint)((QTableWidget *)widget())->rowCount()) - c->warning(__tr2qs_ctx("Item out of the tablewidget size","objects")); - QTableWidgetItem * pItem = ((QTableWidget *)widget())->item(uRow,uCol); - if(!pItem) - { - pItem = new QTableWidgetItem(); - ((QTableWidget *)widget())->setItem(uRow,uCol,pItem); - } - pItem->setData(0,(int)iNumber); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,insertRow) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_uint_t uRow; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) - KVSO_PARAMETERS_END(c) - ((QTableWidget *)widget())->insertRow(uRow); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,insertColumn) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_uint_t uCol; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETERS_END(c) - ((QTableWidget *)widget())->insertColumn(uCol); - return true; -} -KVSO_CLASS_FUNCTION(tablewidget,removeRow) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_uint_t uRow; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) - KVSO_PARAMETERS_END(c) - ((QTableWidget *)widget())->removeRow(uRow); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,removeColumn) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_uint_t uCol; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETERS_END(c) - ((QTableWidget *)widget())->removeColumn(uCol); - return true; -} - - -KVSO_CLASS_FUNCTION(tablewidget,setIcon) -{ - kvs_uint_t uCol,uRow; - KviKvsObject *obPixmap; - kvs_hobject_t obHpixmap; - KviKvsVariant * vPixmap; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) - KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETER("icon",KVS_PT_VARIANT,0,vPixmap) - KVSO_PARAMETERS_END(c) - QPixmap * pix = 0; - if(vPixmap->isHObject()) - { - vPixmap->asHObject(obHpixmap); - obPixmap=KviKvsKernel::instance()->objectController()->lookupObject(obHpixmap); - if(!obPixmap->inheritsClass("pixmap")) - { - c->warning(__tr2qs_ctx("Pixmap object or image Id required","objects")); - return true; - } - pix=((KviKvsObject_pixmap *)obPixmap)->getPixmap(); - } else { - QString szPix; - vPixmap->asString(szPix); - pix=g_pIconManager->getImage(szPix); - if(!pix) - { - c->warning(__tr2qs_ctx("Error occured: the suitable file '%Q' is not of the correct format or it is not a valid icon number.","objects"),&szPix); - return true; - } - } - QTableWidgetItem * pItem = ((QTableWidget *)widget())->item(uRow,uCol); - if(!pItem) - { - pItem = new QTableWidgetItem(); - ((QTableWidget *)widget())->setItem(uRow,uCol,pItem); - } - pItem->setIcon(QIcon(*pix)); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,text) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_uint_t uCol,uRow; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) - KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETERS_END(c) - QTableWidgetItem * pItem = ((QTableWidget *)widget())->item(uRow,uCol); - if(!pItem) c->returnValue()->setNothing(); - else c->returnValue()->setString(((QTableWidget *)widget())->item(uRow,uCol)->text()); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,setRowCount) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_uint_t uRow; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) - KVSO_PARAMETERS_END(c) - ((QTableWidget *)widget())->setRowCount(uRow); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,rowCount) -{ - CHECK_INTERNAL_POINTER(widget()) - c->returnValue()->setInteger(((QTableWidget *)widget())->rowCount()); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,currentRow) -{ - CHECK_INTERNAL_POINTER(widget()) - c->returnValue()->setInteger(((QTableWidget *)widget())->currentRow()); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,currentColumn) -{ - CHECK_INTERNAL_POINTER(widget()) - c->returnValue()->setInteger(((QTableWidget *)widget())->currentColumn()); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,columnCount) -{ - CHECK_INTERNAL_POINTER(widget()) - c->returnValue()->setInteger(((QTableWidget *)widget())->columnCount()); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,itemRowColAt) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_int_t iXpos,iYpos; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("x_pos",KVS_PT_INT,0,iXpos) - KVSO_PARAMETER("y_pos",KVS_PT_INT,0,iYpos) - KVSO_PARAMETERS_END(c) - KviKvsArray *pArray; - QPoint pPoint=((QTableWidget *)widget())->viewport()->mapFromGlobal(QPoint(iXpos,iYpos)); - QTableWidgetItem *pItem=((QTableWidget *)widget())->itemAt(pPoint.x(),pPoint.y()); - pArray=new KviKvsArray; - if (!pItem) { - pArray->set(0,new KviKvsVariant((kvs_int_t)-1)); - pArray->set(1,new KviKvsVariant((kvs_int_t)-1)); - } - else { - pArray->set(0,new KviKvsVariant((kvs_int_t)pItem->row())); - pArray->set(1,new KviKvsVariant((kvs_int_t)pItem->column())); - } - c->returnValue()->setArray(pArray); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,setToolTip) -{ - CHECK_INTERNAL_POINTER(widget()) - QString szTooltip; - kvs_uint_t uRow,uCol; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) - KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETER("tooltip",KVS_PT_STRING,0,szTooltip) - KVSO_PARAMETERS_END(c) - QTableWidgetItem *pItem=((QTableWidget *)widget())->item(uRow,uCol); - if (pItem) pItem->setToolTip(szTooltip); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,setColumnCount) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_uint_t uCol; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETERS_END(c) - ((QTableWidget *)widget())->setColumnCount(uCol); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,hideColumn) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_uint_t uCol; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETERS_END(c) - ((QTableWidget *)widget())->hideColumn(uCol); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,showColumn) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_uint_t uCol; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETERS_END(c) - ((QTableWidget *)widget())->showColumn(uCol); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,hideRow) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_uint_t uRow; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uRow) - KVSO_PARAMETERS_END(c) - ((QTableWidget *)widget())->hideRow(uRow); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,showRow) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_uint_t uRow; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uRow) - KVSO_PARAMETERS_END(c) - ((QTableWidget *)widget())->showRow(uRow); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,setHorizontalHeaderLabels) -{ - CHECK_INTERNAL_POINTER(widget()) - KviKvsArrayCast ac; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("labels",KVS_PT_ARRAYCAST,0,ac) - KVSO_PARAMETERS_END(c) - QStringList szColumns; - if(KviKvsArray * a = ac.array()) - { - kvs_int_t uIdx = 0; - kvs_int_t uSize = a->size(); - while(uIdx < uSize) - { - KviKvsVariant * v = a->at(uIdx); - if(v) - { - QString tmp; - v->asString(tmp); - szColumns.append(tmp); - } - else szColumns.append(""); - uIdx++; - } - } - ((QTableWidget *)object())->setHorizontalHeaderLabels(szColumns); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,setVerticalHeaderLabels) -{ - CHECK_INTERNAL_POINTER(widget()) - KviKvsArrayCast ac; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("labels",KVS_PT_ARRAYCAST,0,ac) - KVSO_PARAMETERS_END(c) - QStringList szColumns; - if(KviKvsArray * a = ac.array()) - { - kvs_int_t uIdx = 0; - kvs_int_t uSize = a->size(); - while(uIdx < uSize) - { - KviKvsVariant * v = a->at(uIdx); - if(v) - { - QString tmp; - v->asString(tmp); - szColumns.append(tmp); - } - else szColumns.append(""); - uIdx++; - } - } - ((QTableWidget *)object())->setVerticalHeaderLabels(szColumns); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,setCellWidget) -{ - CHECK_INTERNAL_POINTER(widget()) - KviKvsObject * pObject; - kvs_hobject_t hObject; - kvs_uint_t uRow,uCol; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) - KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) - KVSO_PARAMETERS_END(c) - pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); - CHECK_HOBJECT_IS_WIDGET(pObject) - ((QTableWidget *)object())->setCellWidget(uRow,uCol,((QWidget *)(pObject->object()))); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,hideHorizontalHeader) -{ - Q_UNUSED(c); - ((QTableWidget *)widget())->horizontalHeader()->hide(); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,hideVerticalHeader) -{ - Q_UNUSED(c); - ((QTableWidget *)widget())->verticalHeader()->hide(); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,showHorizontalHeader) -{ - Q_UNUSED(c); - ((QTableWidget *)widget())->horizontalHeader()->show(); - return true; -} - -KVSO_CLASS_FUNCTION(tablewidget,showVerticalHeader) -{ - Q_UNUSED(c); - ((QTableWidget *)widget())->verticalHeader()->show(); - return true; -} -KVSO_CLASS_FUNCTION(tablewidget,setItemFlags) -{ - CHECK_INTERNAL_POINTER(widget()) - - QStringList itemflags; - kvs_uint_t iRow,iCol; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,iRow) - KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,iCol) - KVSO_PARAMETER("flags",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,itemflags) - KVSO_PARAMETERS_END(c) - int flag,sum=0; - for ( int i=0;isetCheckState(0,Qt::Unchecked); - sum = sum | flag; - } else { - c->warning(__tr2qs_ctx("Unknown item flag '%Q'","objects"),&itemflags.at(i)); - } - } - QTableWidgetItem *pItem=((QTableWidget *)widget())->item(iRow,iCol); - if(pItem) pItem->setFlags((Qt::ItemFlags)sum); - return true; -} - -void KviKvsObject_tablewidget::slotItemEntered(QTableWidgetItem * i) -{ - KviKvsVariantList params(new KviKvsVariant((kvs_int_t)i->row()),new KviKvsVariant((kvs_int_t)i->column())); - callFunction(this,"itemEnteredEvent",0,¶ms); -} - -KVSO_CLASS_FUNCTION(tablewidget,itemEnteredEvent) -{ - emitSignal("itemEntered",c,c->params()); - return true; -} - -void KviKvsObject_tablewidget::cellActivated(int iRow,int iCol) -{ - KviKvsVariantList params(new KviKvsVariant((kvs_int_t)iRow),new KviKvsVariant((kvs_int_t)iCol)); - callFunction(this,"cellActivatedEvent",0,¶ms); -} - -KVSO_CLASS_FUNCTION(tablewidget,cellActivatedEvent) -{ - emitSignal("cellActivated",c,c->params()); - return true; -} - -void KviKvsObject_tablewidget::cellDoubleClicked(int iRow,int iCol) -{ - KviKvsVariantList params(new KviKvsVariant((kvs_int_t)iRow),new KviKvsVariant((kvs_int_t)iCol)); - callFunction(this,"cellDoubleClickedEvent",0,¶ms); -} - -KVSO_CLASS_FUNCTION(tablewidget,cellDoubleClickedEvent) -{ - emitSignal("cellDoubleClicked",c,c->params()); - return true; -} -bool KviKvsObject_tablewidget::paint(QPainter * p, const QStyleOptionViewItem & option, const QModelIndex & index) -{ - p->save(); - KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass("painter"); - KviKvsVariantList params; - KviKvsObject * pObject = pClass->allocateInstance(0,"internalpainter",m_pContext,¶ms); - ((KviKvsObject_painter *)pObject)->setInternalPainter(p); - p->setClipRect(option.rect); - p->translate(option.rect.x(),option.rect.y()); - int col=index.column(); - int row=index.row(); - kvs_hobject_t handle=pObject->handle(); - kvs_int_t cell_height=(kvs_int_t)option.rect.height(); - kvs_int_t cell_width=(kvs_int_t)option.rect.width(); - KviKvsVariantList parameters(new KviKvsVariant(handle),new KviKvsVariant((kvs_int_t) row),new KviKvsVariant((kvs_int_t) col),new KviKvsVariant(cell_width),new KviKvsVariant(cell_height)); - bool ret=false; - KviKvsVariant *retv=new KviKvsVariant(ret); - callFunction(this,"paintCellEvent",retv,¶meters); - pObject=KviKvsKernel::instance()->objectController()->lookupObject(handle); - if (pObject) pObject->dieNow(); - p->restore(); - return retv->asBoolean(); -} - -KviCellItemDelegate::KviCellItemDelegate(QAbstractItemView * pWidget,KviKvsObject_tablewidget * parent) -: QItemDelegate(pWidget), m_pParentScript(parent) -{ -} - -KviCellItemDelegate::~KviCellItemDelegate() -{ -} - -void KviCellItemDelegate::paint(QPainter * pPainter, const QStyleOptionViewItem & option, const QModelIndex & index) const -{ - if (m_pParentScript->paint(pPainter,option,index)) - QItemDelegate::paint(pPainter,option,index); -} - -QSize KviCellItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex & index) const -{ - KviKvsVariant *sizeret=new KviKvsVariant(); - //qDebug("sizehint cell"); - KviKvsVariantList parameters(new KviKvsVariant((kvs_int_t) index.row()),new KviKvsVariant((kvs_int_t) index.column())); - m_pParentScript->callFunction(m_pParentScript,"sizeHintCellRequestEvent",sizeret,¶meters); - if (sizeret->isArray()) - { - if (sizeret->array()->size()==2) - { - kvs_int_t w,h; - if (sizeret->array()->at(0)->asInteger(w) && sizeret->array()->at(1)->asInteger(h))return QSize(w,h); - } - } - return QItemDelegate::sizeHint(option,index); -} - - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_class_tablewidget.moc" -#endif //COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/objects/class_tablewidget.h b/src/modules/objects/class_tablewidget.h deleted file mode 100644 index 2f018aac0..000000000 --- a/src/modules/objects/class_tablewidget.h +++ /dev/null @@ -1,116 +0,0 @@ -#ifndef _CLASS_TABLEWIDGET_H_ -#define _CLASS_TABLEWIDGET_H_ -//============================================================================= -// -// File : class_tablewidget.h -// Creation date : Wed 4 Feb 2009 09:30:05 CEST by Carbone Alessandro -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000 Krzysztof Godlewski -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "class_widget.h" -#include "object_macros.h" - -#include "KviKvsRunTimeContext.h" - -#include -#include -#include -#include - -class KviKvsObject_tablewidget; - -class KviCellItemDelegate : public QItemDelegate -{ -public: - KviCellItemDelegate(QAbstractItemView * pWidget = 0,KviKvsObject_tablewidget *pParent=0); - ~KviCellItemDelegate(); -protected: -// QAbstractItemView * m_pParent; - KviKvsObject_tablewidget *m_pParentScript; -public: - QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const; - void paint(QPainter * pPainter, const QStyleOptionViewItem & option, const QModelIndex & index) const; -}; - -class KviKvsObject_tablewidget : public KviKvsObject_widget -{ - Q_OBJECT -public: - KVSO_DECLARE_OBJECT(KviKvsObject_tablewidget) -public: - QWidget * widget() { return (QWidget *)object(); }; - bool paint(QPainter * pPainter, const QStyleOptionViewItem & option, const QModelIndex & index); - -protected: - QSqlQueryModel * model; - KviKvsRunTimeContext * m_pContext; - KviCellItemDelegate * m_pCellItemDelegate; -protected: - virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); - - bool setText(KviKvsObjectFunctionCall *c); - bool setNumber(KviKvsObjectFunctionCall *c); - bool setToolTip(KviKvsObjectFunctionCall *c); - bool text(KviKvsObjectFunctionCall *c); - bool setIcon(KviKvsObjectFunctionCall *c); - bool setItemFlags(KviKvsObjectFunctionCall *c); - - bool setColumnCount(KviKvsObjectFunctionCall *c); - bool columnCount(KviKvsObjectFunctionCall *c); - bool setRowCount(KviKvsObjectFunctionCall *c); - bool currentRow(KviKvsObjectFunctionCall *c); - bool currentColumn(KviKvsObjectFunctionCall *c); - bool itemRowColAt(KviKvsObjectFunctionCall *c); - - bool rowCount(KviKvsObjectFunctionCall *c); - - bool insertRow(KviKvsObjectFunctionCall *c); - bool insertColumn(KviKvsObjectFunctionCall *c); - bool removeRow(KviKvsObjectFunctionCall *c); - bool removeColumn(KviKvsObjectFunctionCall *c); - - - bool setHorizontalHeaderLabels(KviKvsObjectFunctionCall *c); - bool setVerticalHeaderLabels(KviKvsObjectFunctionCall *c); - bool setCellWidget(KviKvsObjectFunctionCall *c); - - bool hideHorizontalHeader(KviKvsObjectFunctionCall *c); - bool showHorizontalHeader(KviKvsObjectFunctionCall *c); - bool hideVerticalHeader(KviKvsObjectFunctionCall *c); - bool showVerticalHeader(KviKvsObjectFunctionCall *c); - bool clear(KviKvsObjectFunctionCall *c); - bool itemEnteredEvent(KviKvsObjectFunctionCall *c); - bool cellActivatedEvent(KviKvsObjectFunctionCall *c); - bool cellDoubleClickedEvent(KviKvsObjectFunctionCall *c); - - bool hideColumn(KviKvsObjectFunctionCall *c); - bool showColumn(KviKvsObjectFunctionCall *c); - bool hideRow(KviKvsObjectFunctionCall *c); - bool showRow(KviKvsObjectFunctionCall *c); - bool resizeRowsToContents(KviKvsObjectFunctionCall *c); - bool resizeColumnsToContents(KviKvsObjectFunctionCall *c); -protected slots: - void slotItemEntered(QTableWidgetItem *); - void cellActivated(int iRow,int iCol); - void cellDoubleClicked(int iRow,int iCol); -}; - -#endif // !_CLASS_TABLEWIDGET_H_ diff --git a/src/modules/objects/class_tabwidget.cpp b/src/modules/objects/class_tabwidget.cpp deleted file mode 100644 index a416835a2..000000000 --- a/src/modules/objects/class_tabwidget.cpp +++ /dev/null @@ -1,456 +0,0 @@ -//============================================================================= -// -// File : class_tabwidget.cpp -// Creation date : Fri Mar 18 14:30:48 CEST 2005 -// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "class_tabwidget.h" -#include "KviError.h" -#include "kvi_debug.h" -#include "KviLocale.h" -#include "KviIconManager.h" - -#include - -/* - @doc: tabwidget - @keyterms: - tabwidget object class, - @title: - tabwidget class - @type: - class - @short: - Provides a Tab Widget. - @inherits: - [class]object[/class] - [class]widget[/class] - @description: - The tabwidget class provides a stack of tabbed widgets.[br] - Each tab is associated with a different widget (called a `page').[br] - Only the current tab's page is shown in the page area; all the others tabs pages are hidden.[br] - The user can show a different page by clicking on its tab.[br] - @functions: - !fn: $addTab(,,[]) - Adds another page to the tab view with the text label and optional icon. - !fn: $insertTab(,,) - Inserts another tab and page to the tab view with name and label-text specified.[br] - If index is not specified, the tab is simply appended.[br] - Otherwise the new tab is inserted at the specified position. - !fn: $setTabToolTip(,) - Sets the tab tool tip for the tabwidget to . - !fn: $removeTabToolTip() - Removes the tab tool tip for the tab. If the page does not have a tip, nothing happens. - !fn: $setTabLabel(, ) - Sets the tab label for to label. - !fn: $changeTab(,,[]) - Defines a new label, and optional icon, for the tab . - !fn: $setCurrentPage() - Sets the index position of the current tab page to . - !fn: $currentPageIndex() - Returns the current page index. - !fn: $tabLabel() - Returns the tab label of the . - !fn: $widgetAt() - Returns the tab widget of the or 0 if index is out of the tabs count. - !fn: $currentTabLabel() - Returns the label of the current tab. - !fn: $removePage() - Remove the page . - !fn: $setTabPosition() - Sets TabPosition. Valid parameters are : Top, Bottom. - !fn: $count() - Returns the number of tabs in the tab bar. - !fn: $setTabsClosable() - Sets whether close buttons are automatically added to each tab - !fn: $currentChangedEvent() - This function is invoched when the current tab was changed.[br] - The default implementation emits the [classfnc]$currentChange[/classfnc]() signal. - !fn: $tabCloseRequestEvent() - This function is invoched when when the close button on a tab is clicked. - The index is the index of the tab that should be removed.[br] - The default implementation emits the [classfnc]$tabCloseRequest[/classfnc]() signal. - See also [classfnc]$setTabsClosable[/classfnc](). - @examples: - [example] - // First we'll create the main tabwidget. - %Tabwidget=$new(tabwidget) - %Tabwidget->$setToolTip("Example of TabWidget class") - %Tabwidget->$setTabPosition(Top) - %Tabwidget->$resize(300,200) - // Now we'll create the new widgets and put they in to the main tabwidget. - %firsttab=$new(vbox) - %secondtab=$new(vbox) - // Now we'll create the item to put in to tab's pages. - // First tab - %hbox=$new(hbox,%firsttab) - %labelbt=$new(label,%hbox) - %labelbt->$settext(Botton Tab) - %labeltt=$new(label,%hbox) - %labeltt->$settext(Top Tab) - %hbox=$new(hbox,%firsttab) - %buttontb=$new(button,%hbox) - %buttontb->$settext("To &Botton") - %buttontt=$new(button,%hbox) - %buttontt->$settext("To &Top") - // Now we'll give a layout to all items. - // This also allows to use privateimpl without making buttons global variables - // Add the page to the main tab. - %Tabwidget->$addTab(%firsttab,Top&Button,33) - // Implementing the action to do when the user click the buttons. - privateimpl(%buttontb,mousepressevent) - { - %Tabwidget->$setTabPosition(Bottom) - } - privateimpl(%buttontt,mousepressevent) - { - %Tabwidget->$setTabPosition(Top) - } - // We do the same work with the second tab's page. - %labelwp=$new(label,%secondtab) - %labelwp->$settext("Enjoy the new Class provided by") - %labelwp->$setalignment("Center") - %labelgen=$new(label,%secondtab) - %labelgen->$settext(Grifisx \& Noldor) - %labelgen->$setalignment("Center") - %Tabwidget->$addTab(%secondtab,&About,50) - // Let's show our example. - %Tabwidget->$show() - [/example] - @signals: - !sg: $currentChange() - This signal is emitted by the default implementation of [classfnc]$currentChangedEvent[/classfnc]().[br] - If you reimplement that function you will have to emit the signal manually (if you still need it).[br] - !sg: $tabCloseRequest() - This signal is emitted by the default implementation of [classfnc]tabCloseRequestEvent[/classfnc]().[br] -*/ - -KVSO_BEGIN_REGISTERCLASS(KviKvsObject_tabwidget,"tabwidget","widget") - - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tabwidget,addTab) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tabwidget,insertTab) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tabwidget,setTabToolTip) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tabwidget,removeTabToolTip) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tabwidget,setTabLabel) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tabwidget,changeTab) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tabwidget,setCurrentPage) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tabwidget,currentPageIndex) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tabwidget,tabLabel) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tabwidget,currentTabLabel) - - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tabwidget,count) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tabwidget,removePage) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tabwidget,widgetAt) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tabwidget,setTabPosition) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tabwidget,setTabsClosable) - - // events - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tabwidget,currentChangedEvent) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_tabwidget,tabCloseRequestEvent) - - - -KVSO_END_REGISTERCLASS(KviKvsObject_tabwidget) - -KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_tabwidget,KviKvsObject_widget) - -KVSO_END_CONSTRUCTOR(KviKvsObject_tabwidget) - - -KVSO_BEGIN_DESTRUCTOR(KviKvsObject_tabwidget) -tabsList.clear();; -KVSO_END_CONSTRUCTOR(KviKvsObject_tabwidget) - -bool KviKvsObject_tabwidget::init(KviKvsRunTimeContext *,KviKvsVariantList *) -{ - SET_OBJECT(QTabWidget) - connect(widget(),SIGNAL(currentChanged(int)),this,SLOT(slotCurrentChanged(int))); - connect(widget(),SIGNAL(tabCloseRequested(int)),this,SLOT(slotTabCloseRequest(int))); - - return true; -} -KVSO_CLASS_FUNCTION(tabwidget,setTabsClosable) -{ - CHECK_INTERNAL_POINTER(widget()) - bool bClosable; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("bool_flag",KVS_PT_BOOLEAN,0,bClosable) - KVSO_PARAMETERS_END(c) - ((QTabWidget *)widget())->setTabsClosable(bClosable); - return true; -} - -KVSO_CLASS_FUNCTION(tabwidget,addTab) -{ - CHECK_INTERNAL_POINTER(widget()) - KviKvsObject *pObject; - QString szLabel,szIcon; - kvs_hobject_t hObject; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) - KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel) - KVSO_PARAMETER("icon_id",KVS_PT_STRING,KVS_PF_OPTIONAL,szIcon) - KVSO_PARAMETERS_END(c) - pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); - CHECK_HOBJECT_IS_WIDGET(pObject) - QPixmap * pix = g_pIconManager->getImage(szIcon); - if(pix){ - ((QTabWidget *)widget())->addTab(((QWidget *)(pObject->object())),QIcon(*pix),szLabel); - } - else((QTabWidget *)widget())->addTab(((QWidget *)(pObject->object())),szLabel); - tabsList.append(hObject); - return true; -} -KVSO_CLASS_FUNCTION(tabwidget,widgetAt) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_int_t iIndex; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("index",KVS_PT_INTEGER,0,iIndex) - KVSO_PARAMETERS_END(c) - if (iIndex>=tabsList.count()||iIndex<0) c->returnValue()->setHObject((kvs_hobject_t)0); - else c->returnValue()->setHObject(tabsList.at(iIndex)); - return true; -} - -KVSO_CLASS_FUNCTION(tabwidget,insertTab) -{ - CHECK_INTERNAL_POINTER(widget()) - KviKvsObject *pObject; - QString szLabel,szIcon; - kvs_uint_t uIndex; - kvs_hobject_t hObject; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("tab_widget",KVS_PT_HOBJECT,0,hObject) - KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel) - KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,uIndex) - KVSO_PARAMETER("icon_id",KVS_PT_STRING,KVS_PF_OPTIONAL,szIcon) - KVSO_PARAMETERS_END(c) - pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); - CHECK_HOBJECT_IS_WIDGET(pObject) - QPixmap * pix = g_pIconManager->getImage(szIcon); - if(pix){ - ((QTabWidget *)widget())->insertTab(uIndex,(QWidget *)(pObject->object()),QIcon(*pix),szLabel); - } - else ((QTabWidget *)widget())->insertTab(uIndex,((QWidget *)(pObject->object())),szLabel); - tabsList.insert(uIndex,hObject); - return true; -} - -KVSO_CLASS_FUNCTION(tabwidget,setCurrentPage) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_uint_t iIndex; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("index",KVS_PT_UNSIGNEDINTEGER,0,iIndex) - KVSO_PARAMETERS_END(c) - ((QTabWidget *)widget())->setCurrentIndex(iIndex); - return true; -} -KVSO_CLASS_FUNCTION(tabwidget,setTabToolTip) -{ - CHECK_INTERNAL_POINTER(widget()) - KviKvsObject *pObject; - QString szTooltip; - kvs_hobject_t hObject; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("tab_widget",KVS_PT_HOBJECT,0,hObject) - KVSO_PARAMETER("tooltip",KVS_PT_STRING,0,szTooltip) - KVSO_PARAMETERS_END(c) - pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); - CHECK_HOBJECT_IS_WIDGET(pObject) - int iIdx = ((QTabWidget *)widget())->indexOf (((QWidget *)(pObject->object()))); - if (iIdx == -1) - { - c->warning(__tr2qs_ctx("Can't find the tab ","objects")); - return true; - } - ((QTabWidget *)widget())->setTabToolTip(iIdx,szTooltip); - return true; -} -KVSO_CLASS_FUNCTION(tabwidget,removeTabToolTip) -{ - CHECK_INTERNAL_POINTER(widget()) - KviKvsObject *pObject; - kvs_hobject_t hObject; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("tab_widget",KVS_PT_HOBJECT,0,hObject) - KVSO_PARAMETERS_END(c) - pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); - CHECK_HOBJECT_IS_WIDGET(pObject) - int iIdx = ((QTabWidget *)widget())->indexOf (((QWidget *)(pObject->object()))) ; - if (iIdx==-1) - { - c->warning(__tr2qs_ctx("Can't find the tab ","objects")); - return true; - } - ((QTabWidget *)widget())->setTabToolTip(iIdx,QString()); - return true; -} - -KVSO_CLASS_FUNCTION(tabwidget,setTabLabel) -{ - CHECK_INTERNAL_POINTER(widget()) - KviKvsObject *pObject; - QString szLabel; - kvs_hobject_t hObject; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("tab_widget",KVS_PT_HOBJECT,0, hObject) - KVSO_PARAMETER("tooltip",KVS_PT_STRING,0,szLabel) - KVSO_PARAMETERS_END(c) - pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); - CHECK_HOBJECT_IS_WIDGET(pObject) - int iIdx = ((QTabWidget *)widget())->indexOf (((QWidget *)(pObject->object()))); - if (iIdx == -1) - { - c->warning(__tr2qs_ctx("Can't find the tab ","objects")); - return true; - } - ((QTabWidget *)widget())->setTabText(iIdx,szLabel); - return true; -} -KVSO_CLASS_FUNCTION(tabwidget,currentPageIndex) -{ - CHECK_INTERNAL_POINTER(widget()) - int index=((QTabWidget *)widget())->currentIndex(); - c->returnValue()->setInteger(index); - return true; -} -KVSO_CLASS_FUNCTION(tabwidget,tabLabel) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_int_t uIndex; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("index",KVS_PT_INT,0,uIndex) - KVSO_PARAMETERS_END(c) - QString label=((QTabWidget *)widget())->tabText(uIndex); - c->returnValue()->setString(label); - return true; -} - - -KVSO_CLASS_FUNCTION(tabwidget,count) -{ - CHECK_INTERNAL_POINTER(widget()) - int count = ((QTabWidget *)widget())->count(); - c->returnValue()->setInteger(count); - return true; -} - -KVSO_CLASS_FUNCTION(tabwidget,currentTabLabel) -{ - CHECK_INTERNAL_POINTER(widget()) - int i= ((QTabWidget *)widget())->currentIndex(); - QString label=((QTabWidget *)widget())->tabText(i); - c->returnValue()->setString(label); - return true; -} -KVSO_CLASS_FUNCTION(tabwidget,removePage) -{ - CHECK_INTERNAL_POINTER(widget()) - KviKvsObject *pObject; - kvs_hobject_t hObject; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("tab_widget",KVS_PT_HOBJECT,0,hObject) - KVSO_PARAMETERS_END(c) - pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); - CHECK_HOBJECT_IS_WIDGET(pObject) - int iIdx = ((QTabWidget *)widget())->indexOf (((QWidget *)(pObject->object()))); - if (iIdx == -1) - { - c->warning(__tr2qs_ctx("Can't find the tab ","objects")); - return true; - } - ((QTabWidget *)widget())->removeTab(iIdx); - tabsList.removeAt(iIdx); - return true; -} - -KVSO_CLASS_FUNCTION(tabwidget,changeTab) -{ - CHECK_INTERNAL_POINTER(widget()) - KviKvsObject *pObject; - QString szLabel,szIcon; - kvs_hobject_t hObject; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("tab_widget",KVS_PT_HOBJECT,0,hObject) - KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel) - KVSO_PARAMETER("icon_id",KVS_PT_STRING,KVS_PF_OPTIONAL,szIcon) - KVSO_PARAMETERS_END(c) - pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); - CHECK_HOBJECT_IS_WIDGET(pObject) - int iIdx = ((QTabWidget *)widget())->indexOf (((QWidget *)(pObject->object()))); - if (iIdx == -1) - { - c->warning(__tr2qs_ctx("Can't find the tab","objects")); - return true; - } - QPixmap * pix = g_pIconManager->getImage(szIcon); - if(pix)((QTabWidget *)widget())->setTabIcon(iIdx,QIcon(*pix)); - ((QTabWidget *)widget())->setTabText(iIdx,szLabel); - return true; -} - -KVSO_CLASS_FUNCTION(tabwidget,setTabPosition) -{ - CHECK_INTERNAL_POINTER(widget()) - QString szPos; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("tab_position",KVS_PT_STRING,0,szPos) - KVSO_PARAMETERS_END(c) - if(KviQString::equalCI(szPos,"Top")) - ((QTabWidget *)widget())->setTabPosition(QTabWidget::North); - else if(KviQString::equalCI(szPos,"Bottom")) - ((QTabWidget *)widget())->setTabPosition(QTabWidget::South); - else c->warning( __tr2qs_ctx("Unknown position '%Q'","objects"),&szPos); - return true; -} - -KVSO_CLASS_FUNCTION(tabwidget,currentChangedEvent) -{ - - emitSignal("currentChanged",c,c->params()); - return true; -} - -void KviKvsObject_tabwidget::slotCurrentChanged(int value) -{ - KviKvsVariantList params(new KviKvsVariant((kvs_int_t)value)); - callFunction(this,"currentChangedEvent",¶ms); -} - -KVSO_CLASS_FUNCTION(tabwidget,tabCloseRequestEvent) -{ - - emitSignal("tabCloseRequested",c,c->params()); - return true; -} - -void KviKvsObject_tabwidget::slotTabCloseRequest(int iIndex) -{ - KviKvsVariantList params(new KviKvsVariant((kvs_int_t)iIndex)); - callFunction(this,"tabCloseRequestEvent",¶ms); -} -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_class_tabwidget.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES - diff --git a/src/modules/objects/class_tabwidget.h b/src/modules/objects/class_tabwidget.h deleted file mode 100644 index a8425a3b7..000000000 --- a/src/modules/objects/class_tabwidget.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef _CLASS_TABWIDGET_H_ -#define _CLASS_TABWIDGET_H_ -//============================================================================= -// -// File : class_tabwidget.cpp -// Creation date : Fri Mar 18 14:30:48 CEST 2005 -// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "class_widget.h" -#include "object_macros.h" - -class KviKvsObject_tabwidget : public KviKvsObject_widget -{ - Q_OBJECT -public: - KVSO_DECLARE_OBJECT(KviKvsObject_tabwidget) -public: - QWidget * widget() { return (QWidget *)object(); }; -protected: - virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); - QList tabsList; - - bool addTab(KviKvsObjectFunctionCall *c); - bool insertTab(KviKvsObjectFunctionCall *c); - bool setTabToolTip(KviKvsObjectFunctionCall *c); - bool removeTabToolTip(KviKvsObjectFunctionCall *c); - bool setTabLabel(KviKvsObjectFunctionCall *c); - bool setCurrentPage(KviKvsObjectFunctionCall *c); - bool currentPageIndex(KviKvsObjectFunctionCall *c); - bool tabLabel(KviKvsObjectFunctionCall *c); - bool currentTabLabel(KviKvsObjectFunctionCall *c); - bool count(KviKvsObjectFunctionCall *c); - bool changeTab(KviKvsObjectFunctionCall *c); - bool removePage(KviKvsObjectFunctionCall *c); - bool setTabPosition(KviKvsObjectFunctionCall *c); - bool setTabsClosable(KviKvsObjectFunctionCall *c); - bool widgetAt(KviKvsObjectFunctionCall *c); - - // events - bool currentChangedEvent(KviKvsObjectFunctionCall *c); - bool tabCloseRequestEvent(KviKvsObjectFunctionCall *c); - -protected slots: - void slotCurrentChanged(int); - void slotTabCloseRequest(int); -}; - -#endif //!_CLASS_TABWIDGET_H_ diff --git a/src/modules/objects/class_tbrowser.cpp b/src/modules/objects/class_tbrowser.cpp deleted file mode 100644 index 8be17b779..000000000 --- a/src/modules/objects/class_tbrowser.cpp +++ /dev/null @@ -1,155 +0,0 @@ -//============================================================================= -// -// File : class_tbrowser.cpp -// Creation date : Fri Mar 18 14:30:48 CEST 2005 -// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - - -#include "class_tbrowser.h" -#include "KviError.h" -#include "kvi_debug.h" -#include "KviLocale.h" -#include "KviIconManager.h" - -#include -#include -#include -/* - @doc: textbrowser - @keyterms: - textbrowser browser widget class, - @title: - textbrowser class - @type: - class - @short: - Provides a class that can display html pages. - @inherits: - [class]widget[/class] - @description: - Provides a class that can display html pages with hypertext navigation. - @functions: - !fn: $setSource() - With this you can display the page at szFile location (szFile include the path). - !fn: $backward() - Changes the document displayed to the previous document in the list of documents built by navigating links. - !fn: $forward() - Changes the document displayed to the next document in the list of documents built by navigating links. - !fn: $home() - Changes the document displayed to be the first document the browser displayed. - !fn: $reload() - Reloads the current set source. - !fn: $linkClickedEvent() - Triggered when a link is clicked by the user. The default implementation of this function - emits the "linkClicked" signal. - @signals: - !sg: $linkClicked() - This signal is emitted by the default implementation of the [classfnc]$linkClickedEvent[/classfnc]() function. -*/ - -KVSO_BEGIN_REGISTERCLASS(KviKvsObject_textbrowser,"textbrowser","multilineedit") - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_textbrowser,setSource) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_textbrowser,forward) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_textbrowser,backward) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_textbrowser,home) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_textbrowser,reload) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_textbrowser,linkClickedEvent) -KVSO_END_REGISTERCLASS(KviKvsObject_textbrowser) - -KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_textbrowser,KviKvsObject_textedit) - -KVSO_END_CONSTRUCTOR(KviKvsObject_textbrowser) - - -KVSO_BEGIN_DESTRUCTOR(KviKvsObject_textbrowser) - -KVSO_END_CONSTRUCTOR(KviKvsObject_textbrowser) - -bool KviKvsObject_textbrowser::init(KviKvsRunTimeContext *,KviKvsVariantList *) -{ - SET_OBJECT(QTextBrowser); - connect(obj,SIGNAL(anchorClicked(const QUrl &)),this,SLOT(anchorClicked(const QUrl &))); - return true; -} - -KVSO_CLASS_FUNCTION(textbrowser,setSource) -{ - CHECK_INTERNAL_POINTER(widget()) - QString szFile; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("file_name",KVS_PT_STRING,0,szFile) - KVSO_PARAMETERS_END(c) - if(!QFile::exists(szFile)) - { - c->warning(__tr2qs_ctx("I can't find the specified file '%Q'.","objects"),&szFile); - return true; - } - QUrl url; - url.setPath(szFile); - ((QTextBrowser *)widget())->setSource(url); - return true; -} - -KVSO_CLASS_FUNCTION(textbrowser,forward) -{ - CHECK_INTERNAL_POINTER(widget()) - ((QTextBrowser *)widget())->forward(); - return true; -} - -KVSO_CLASS_FUNCTION(textbrowser,backward) -{ - CHECK_INTERNAL_POINTER(widget()) - ((QTextBrowser *)widget())->backward(); - return true; -} - -KVSO_CLASS_FUNCTION(textbrowser,home) -{ - CHECK_INTERNAL_POINTER(widget()) - ((QTextBrowser *)widget())->home(); - return true; -} - -KVSO_CLASS_FUNCTION(textbrowser,reload) -{ - CHECK_INTERNAL_POINTER(widget()) - ((QTextBrowser *)widget())->reload(); - return true; -} - -void KviKvsObject_textbrowser::anchorClicked(const QUrl &url) -{ - KviKvsVariantList parms(new KviKvsVariant(url.path())); - callFunction(this,"linkClickedEvent",0,&parms); -} - -KVSO_CLASS_FUNCTION(textbrowser,linkClickedEvent) -{ - emitSignal("linkClicked",c,c->params()); - return true; -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_class_tbrowser.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES - diff --git a/src/modules/objects/class_tbrowser.h b/src/modules/objects/class_tbrowser.h deleted file mode 100644 index aedfdd42d..000000000 --- a/src/modules/objects/class_tbrowser.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef _CLASS_TBROWSER_H_ -#define _CLASS_TBROWSER_H_ -//============================================================================= -// -// File : class_tbrowser.h -// Creation date : Fri Mar 18 14:30:48 CEST 2005 -// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "class_widget.h" -#include "class_multilineedit.h" -#include "object_macros.h" -#include -class KviKvsObject_textbrowser : public KviKvsObject_textedit -{ - Q_OBJECT -public: - KVSO_DECLARE_OBJECT(KviKvsObject_textbrowser) -public: - QWidget * widget() { return (QWidget *)object(); }; -protected: - virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); - - bool setSource(KviKvsObjectFunctionCall *c); - bool forward(KviKvsObjectFunctionCall *c); - bool backward(KviKvsObjectFunctionCall *c); - bool home(KviKvsObjectFunctionCall *c); - bool reload(KviKvsObjectFunctionCall *c); - bool linkClickedEvent(KviKvsObjectFunctionCall *c); -protected slots: - void anchorClicked(const QUrl &); -}; - -#endif //!_CLASS_TBROWSER_H_ diff --git a/src/modules/objects/class_toolbar.cpp b/src/modules/objects/class_toolbar.cpp deleted file mode 100644 index 017b7a9c8..000000000 --- a/src/modules/objects/class_toolbar.cpp +++ /dev/null @@ -1,128 +0,0 @@ -//============================================================================= -// -// File : class_toolbar.cpp -// Creation date : Fri Mar 18 14:30:48 CEST 2005 -// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "class_toolbar.h" -#include "KviError.h" -#include "kvi_debug.h" -#include "KviTalToolBar.h" -#include "KviTalMainWindow.h" -#include "KviLocale.h" -#include "KviIconManager.h" -#include "class_mainwindow.h" - -/* - @doc: toolbar - @keyterms: - toolbar object class, - @title: - toolbar class - @type: - class - @short: - Provides a toolbar for mainwindow widget. - @inherits: - [class]object[/class] - [class]widget[/class] - @description: - The toolbar class provides a movable panel containing widgets such as tool buttons. - @functions: - !fn: $addSeparator() - Adds a separator to the right/bottom of the toolbar. - !fn: $setLabel() - Sets the toolbar's label. - !fn: $label() - Returns the toolbar's label. - !fn: $clear() - Deletes all the toolbar's child widgets. - -*/ - - -KVSO_BEGIN_REGISTERCLASS(KviKvsObject_toolbar,"toolbar","widget") - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbar,addSeparator) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbar,setLabel) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbar,label) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbar,clear) -KVSO_END_REGISTERCLASS(KviKvsObject_toolbar) - -KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_toolbar,KviKvsObject_widget) - -KVSO_END_CONSTRUCTOR(KviKvsObject_toolbar) - - -KVSO_BEGIN_DESTRUCTOR(KviKvsObject_toolbar) - -KVSO_END_CONSTRUCTOR(KviKvsObject_toolbar) - -bool KviKvsObject_toolbar::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *) -{ - if (!parentObject()) - { - pContext->warning(__tr2qs_ctx("The toolbar cannot be a parent-widget!","objects")); - return true; - } - if(parentObject()->inheritsClass("mainwindow")) - { - setObject(new KviTalToolBar(getName(), ((KviTalMainWindow *)parentScriptWidget())), true); - } - else - { - pContext->warning(__tr2qs_ctx("The parent-widget isn't a MainWindow.","objects")); - } - - return true; -} - -KVSO_CLASS_FUNCTION(toolbar,addSeparator) -{ - CHECK_INTERNAL_POINTER(widget()) - ((KviTalToolBar *)widget())->addSeparator(); - return true; -} -KVSO_CLASS_FUNCTION(toolbar,setLabel) -{ - CHECK_INTERNAL_POINTER(widget()) - QString szLabel; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel) - KVSO_PARAMETERS_END(c) - ((KviTalToolBar *)widget())->setWindowTitle(szLabel); - return true; -} -KVSO_CLASS_FUNCTION(toolbar,label) -{ - CHECK_INTERNAL_POINTER(widget()) - c->returnValue()->setString(((KviTalToolBar *)widget())->windowTitle()); - return true; -} -KVSO_CLASS_FUNCTION(toolbar,clear) -{ - CHECK_INTERNAL_POINTER(widget()) - ((KviTalToolBar *)object())->clear(); - return true; -} - - - diff --git a/src/modules/objects/class_toolbar.h b/src/modules/objects/class_toolbar.h deleted file mode 100644 index a7bd439d1..000000000 --- a/src/modules/objects/class_toolbar.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef _CLASS_TOOLBAR_H_ -#define _CLASS_TOOLBAR_H_ -//============================================================================= -// -// File : class_toolbar.h -// Creation date : Fri Mar 18 14:30:48 CEST 2005 -// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "class_widget.h" -#include "object_macros.h" - -class KviKvsObject_toolbar : public KviKvsObject_widget -{ -public: - KVSO_DECLARE_OBJECT(KviKvsObject_toolbar) -public: - QWidget * widget() { return (QWidget *)object(); }; -protected: - virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); - - bool addSeparator(KviKvsObjectFunctionCall *c); - bool setLabel(KviKvsObjectFunctionCall *c); - bool label(KviKvsObjectFunctionCall *c); - bool setStretchableWidget(KviKvsObjectFunctionCall *c); - bool clear(KviKvsObjectFunctionCall *c); -}; - - -#endif //!_CLASS_TOOLBAR_H_ diff --git a/src/modules/objects/class_toolbutton.cpp b/src/modules/objects/class_toolbutton.cpp deleted file mode 100644 index 516944445..000000000 --- a/src/modules/objects/class_toolbutton.cpp +++ /dev/null @@ -1,344 +0,0 @@ -//============================================================================= -// -// File : class_toolbutton.cpp -// Creation date : Fri Mar 18 14:30:48 CEST 2005 -// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "class_toolbutton.h" -#include "KviError.h" -#include "kvi_debug.h" - -#include "KviLocale.h" -#include "KviIconManager.h" -#include "KviTalPopupMenu.h" -/* - @doc: toolbutton - @keyterms: - toolbutton object class, - @title: - toolbutton class - @type: - class - @short: - Provides a toolbutton for toolbar widget. - @inherits: - [class]object[/class] - [class]widget[/class] - @description: - The toolbutton class provides a quick-access button to commands or options, usually used inside a ToolBar. - @functions: - !fn:$setImage() - Sets the image for this button. - !fn:$setUsesBigPixmap() - Sets whether this toolbutton uses big pixmaps to enable. - !fn:$usesBigPixmap() - This property holds whether this toolbutton uses big pixmaps. - !fn:setUsesTextLabel() - Sets whether the toolbutton show a texlabel below the pixmap of the button. - !fn:$usesTextLabel() - Return 1 if the setUsesTextLabel is enabled, otherwise return 0. - !fn:$setTextLabel(,[tooltip:string]) - Sets the label of this button to and automatically sets it as a tool tip if is TRUE. - !fn: $textLabel() - Returns the label of tthe button. - !fn:$setAutoRaise() - Sets whether auto-raising is enabled. - !fn: $autoRaise() - Returns 1 if autoRaise is enabled, otherwise returns 0. - !fn:$setToggleButton() - Sets whether the tool button is a toggle button 1 enable, 0 disable. - !fn: $toggle() - Toggles the state of the tool button. - !fn:$setOn() - Sets whether the tool button is on to the bool value: 1 enable, 0 disable. - !fn:$setPopup () - Associates the given with this tool button. - !fn:$openPopup() - Opens the associated popup menu. If there is no such menu, this function does nothing. - !fn:setTextPosition() - Sets the position of the tool button's textLabel in relation to the tool button's icon.[br] - Valid texpos values are:[br] - - BesideIcon : The text appears beside the icon.[br] - - BelowIcon : The text appears below the icon. - !fn: $textPosition() - Returns the position of the text label of this button. - !fn: $clickEvent() - This function is called when the toolbutton is clicked.[br] - You can reimplement it to handle the user click events.[br] - The default implementation emits the [classfnc]$clicked[/classfnc]() signal. - @signals: - !sg: $clicked() - This signal is emitted by the default implementation of [classfnc]$clickEvent[/classfnc]().[br] -*/ - - -KVSO_BEGIN_REGISTERCLASS(KviKvsObject_toolbutton,"toolbutton","widget") - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbutton,setImage) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbutton,setUsesBigPixmap) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbutton,usesBigPixmap) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbutton,setUsesTextLabel) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbutton,usesTextLabel) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbutton,setAutoRaise) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbutton,autoRaise) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbutton,setTextLabel) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbutton,textLabel) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbutton,setPopup) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbutton,openPopup) - - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbutton,setToggleButton) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbutton,toggle) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbutton,setOn) - - - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbutton,setTextPosition) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbutton,textPosition) - - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_toolbutton,clickEvent) -KVSO_END_REGISTERCLASS(KviKvsObject_toolbutton) - -KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_toolbutton,KviKvsObject_widget) - -KVSO_END_CONSTRUCTOR(KviKvsObject_toolbutton) - - -KVSO_BEGIN_DESTRUCTOR(KviKvsObject_toolbutton) - -KVSO_END_CONSTRUCTOR(KviKvsObject_toolbutton) - -bool KviKvsObject_toolbutton::init(KviKvsRunTimeContext *,KviKvsVariantList *) -{ - SET_OBJECT(QToolButton); - connect(widget(),SIGNAL(clicked()),this,SLOT(slotClicked())); - return true; -} - -KVSO_CLASS_FUNCTION(toolbutton,setImage) -{ - CHECK_INTERNAL_POINTER(widget()) - QString icon; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("icon_id",KVS_PT_STRING,0,icon) - KVSO_PARAMETERS_END(c) - QPixmap * pix = g_pIconManager->getImage(icon); - if(pix){ - ((QToolButton *)widget())->setIcon(QIcon(*pix)); - } - else - ((QToolButton *)widget())->setIcon(QIcon()); - return true; -} - -KVSO_CLASS_FUNCTION(toolbutton,setUsesBigPixmap) -{ - CHECK_INTERNAL_POINTER(widget()) - bool bEnabled; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) - KVSO_PARAMETERS_END(c) - ((QToolButton *)widget())->setIconSize(bEnabled ? QSize(32,32) : QSize(22,22)); - return true; -} - -KVSO_CLASS_FUNCTION(toolbutton,usesBigPixmap) -{ - CHECK_INTERNAL_POINTER(widget()) - c->returnValue()->setBoolean(((QToolButton *)widget())->iconSize().height() > 22); - return true; -} - -KVSO_CLASS_FUNCTION(toolbutton,setUsesTextLabel) -{ - CHECK_INTERNAL_POINTER(widget()) - bool bEnabled; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) - KVSO_PARAMETERS_END(c) - ((QToolButton *)widget())->setToolButtonStyle(bEnabled?Qt::ToolButtonTextUnderIcon : Qt::ToolButtonIconOnly); - return true; -} - -KVSO_CLASS_FUNCTION(toolbutton,usesTextLabel) -{ - CHECK_INTERNAL_POINTER(widget()) - c->returnValue()->setBoolean(((QToolButton *)widget())->toolButtonStyle() != Qt::ToolButtonIconOnly); - return true; -} - -KVSO_CLASS_FUNCTION(toolbutton,setAutoRaise) -{ - CHECK_INTERNAL_POINTER(widget()) - bool bEnabled; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) - KVSO_PARAMETERS_END(c) - ((QToolButton *)widget())->setAutoRaise(bEnabled); - return true; -} - -KVSO_CLASS_FUNCTION(toolbutton,autoRaise) -{ - CHECK_INTERNAL_POINTER(widget()) - c->returnValue()->setBoolean(((QToolButton *)widget())->autoRaise()); - return true; -} - -KVSO_CLASS_FUNCTION(toolbutton,setOn) -{ - CHECK_INTERNAL_POINTER(widget()) - bool bEnabled; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) - KVSO_PARAMETERS_END(c) - ((QToolButton *)widget())->setChecked(bEnabled); - return true; -} - -KVSO_CLASS_FUNCTION(toolbutton,setToggleButton) -{ - CHECK_INTERNAL_POINTER(widget()) - bool bEnabled; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) - KVSO_PARAMETERS_END(c) - ((QToolButton *)widget())->setCheckable(bEnabled); - return true; -} - -KVSO_CLASS_FUNCTION(toolbutton,toggle) -{ - CHECK_INTERNAL_POINTER(widget()) - ((QToolButton *)widget())->toggle(); - return true; -} - -KVSO_CLASS_FUNCTION(toolbutton,setTextLabel) -{ - CHECK_INTERNAL_POINTER(widget()) - QString szLabel,szTip; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel) - KVSO_PARAMETER("tooltip",KVS_PT_STRING,KVS_PF_OPTIONAL,szTip) - KVSO_PARAMETERS_END(c) - ((QToolButton *)widget())->setText(szLabel); - if (!szTip.isEmpty()) ((QToolButton *)widget())->setToolTip(szTip); - return true; -} - -KVSO_CLASS_FUNCTION(toolbutton,textLabel) -{ - CHECK_INTERNAL_POINTER(widget()) - c->returnValue()->setString(((QToolButton *)widget())->text()); - return true; -} - -KVSO_CLASS_FUNCTION(toolbutton,setPopup) -{ - CHECK_INTERNAL_POINTER(widget()) - KviKvsObject *ob; - kvs_hobject_t hObject; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) - KVSO_PARAMETERS_END(c) - ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject); - if (!ob) - { - c->warning(__tr2qs_ctx("Widget parameter is not an object","objects")); - return true; - } - if (!ob->object()) - { - c->warning(__tr2qs_ctx("Widget parameter is not a valid object","objects")); - return true; - } - if(!ob->inheritsClass("popupmenu")) - { - c->warning(__tr2qs_ctx("Can't add a non-popupmenu object","objects")); - return true; - } - ((QToolButton *)widget())->setMenu(((KviTalPopupMenu *)(ob->object()))); - return true; -} - -KVSO_CLASS_FUNCTION(toolbutton,openPopup) -{ - CHECK_INTERNAL_POINTER(widget()) - ((QToolButton *)widget())->showMenu(); - return true; -} -/* -KVSO_CLASS_FUNCTION(toolbutton,setPopupDelay) -{ - kvs_int_t uDelay; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("delay",KVS_PT_UNSIGNEDINTEGER,0,uDelay) - KVSO_PARAMETERS_END(c) - if (widget()) - ((QToolButton *)widget())->setPopupDelay(uDelay); - return true; -} -KVSO_CLASS_FUNCTION(toolbutton,popupDelay) -{ - if (widget()) - c->returnValue()->setInteger(((QToolButton *)widget())->popupDelay()); - return true; -} -*/ -KVSO_CLASS_FUNCTION(toolbutton,setTextPosition) -{ - CHECK_INTERNAL_POINTER(widget()) - QString szPos; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("position",KVS_PT_STRING,0,szPos) - KVSO_PARAMETERS_END(c) - if(KviQString::equalCI(szPos,"BesideIcon")) - ((QToolButton *)widget())->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - else if(KviQString::equalCI(szPos,"BelowIcon")) - ((QToolButton *)widget())->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); - else c->warning(__tr2qs_ctx("Unknown text position '%Q'","objects"),&szPos); - return true; -} - -KVSO_CLASS_FUNCTION(toolbutton,textPosition) -{ - CHECK_INTERNAL_POINTER(widget()) - QString szPos="BelowIcon"; - if ((((QToolButton *)widget())->toolButtonStyle())==(Qt::ToolButtonTextBesideIcon)) - szPos="BesideIcon"; - c->returnValue()->setString(szPos); - return true; -} - -KVSO_CLASS_FUNCTION(toolbutton,clickEvent) -{ - emitSignal("clicked",c); - return true; -} - -void KviKvsObject_toolbutton::slotClicked() -{ - KviKvsVariantList *params=0; - callFunction(this,"clickEvent",params); -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_class_toolbutton.moc" -#endif //COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/objects/class_toolbutton.h b/src/modules/objects/class_toolbutton.h deleted file mode 100644 index 519abb58f..000000000 --- a/src/modules/objects/class_toolbutton.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef _CLASS_TOOLBUTTON_H_ -#define _CLASS_TOOLBUTTON_H_ -//============================================================================= -// -// File : class_toolbutton.cpp -// Creation date : Fri Mar 18 14:30:48 CEST 2005 -// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - - - -#include "class_widget.h" -#include "object_macros.h" - -class KviKvsObject_toolbutton : public KviKvsObject_widget -{ - Q_OBJECT -public: - KVSO_DECLARE_OBJECT(KviKvsObject_toolbutton) -public: - QWidget * widget() { return (QWidget *)object(); }; -protected: - virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); - - bool setImage(KviKvsObjectFunctionCall *c); - bool setUsesBigPixmap(KviKvsObjectFunctionCall *c); - bool usesBigPixmap(KviKvsObjectFunctionCall *c); - bool setUsesTextLabel(KviKvsObjectFunctionCall *c); - bool usesTextLabel(KviKvsObjectFunctionCall *c); - bool setTextLabel(KviKvsObjectFunctionCall *c); - bool textLabel(KviKvsObjectFunctionCall *c); - bool setPopup(KviKvsObjectFunctionCall *c); - bool openPopup(KviKvsObjectFunctionCall *c); - bool setOn(KviKvsObjectFunctionCall *c); - bool setToggleButton(KviKvsObjectFunctionCall *c); - bool toggle(KviKvsObjectFunctionCall *c); -// bool setPopupDelay(KviKvsObjectFunctionCall *c); -// bool popupDelay(KviKvsObjectFunctionCall *c); - bool setTextPosition(KviKvsObjectFunctionCall *c); - bool textPosition(KviKvsObjectFunctionCall *c); - - bool setAutoRaise(KviKvsObjectFunctionCall *c); - bool autoRaise(KviKvsObjectFunctionCall *c); - bool clickEvent(KviKvsObjectFunctionCall *c); -signals: - void clicked(); -protected slots: - void slotClicked(); -}; - - -#endif //!_CLASS_TOOLBUTTON_H_ diff --git a/src/modules/objects/class_trayicon.cpp b/src/modules/objects/class_trayicon.cpp deleted file mode 100644 index 55dc31765..000000000 --- a/src/modules/objects/class_trayicon.cpp +++ /dev/null @@ -1,243 +0,0 @@ -//============================================================================= -// -// File : class_trayicon.cpp -// Creation date : Wed Ago 25 17:28:45 2010 GMT by Carbone Alesssandro -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2009 Alessandro Carbone (elfonol at gmail dot com) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "class_trayicon.h" -#include "class_popupmenu.h" -#include "KviIconManager.h" -#include "kvi_debug.h" -#include "KviError.h" -#include "KviLocale.h" - -#include - - - - -/* - @doc: trayicon - @keyterms: - trayicon object class - @title: - trayicon class - @type: - class - @short: - An implementation of the the system tray icon. - @inherits: - [class]object[/class] - @description: - This class provides a standard trayicon functionality.[br] - @functions: - !fn: setIcon(). - Sets the tray icon. - See the [doc:image_id]image identifier[/doc] documentation for the explaination of the parameter. - !fn: setTooltip(). - Sets the tray icon tooltip. - !fn: show() - Shows the tray icon. - !fn: hide() - Hides the tray icon. - !fn: isVisible() - Returns '1' if the tray icon is currently visible. - !fn: showMessage(,,,) - Shows a balloon message for the entry with the given title, message and message_icon for the time specified in millisecondsTimeoutHint. title and message must be plain text strings. - Message can be clicked by the user; the messageClickedEvent() will be triggered when this occurs. - Valid values for message_icon are: - - NoIcon : No icon is shown. - - Information : An information icon is shown. - - Warning : A standard warning icon is shown. - - Critical : A critical warning icon is shown. - !fn: setContextMenu(). - Associates the given with the tray icon. - !fn: activatedEvent() - This event is triggered when the user click the tray icon. - If you reimplement this function the reason parameter will be passed as $0. - Values for reason are: - - Unknown : Unknown reason. - - Context : The context menu for the tray icon was requested. - - DoubleClick : The tray icon was double clicked. - - Trigger : The tray icon was clicked. - - MiddleClick : The tray icon was clicked with the middle mouse button. - The default implementation emits the [classfnc]$activated[/classfnc]() signal. - !fn: messageClickedEvent() - This event is triggered when the message displayed using [classfnc]$showMessage[/classfnc]() was clicked by the user. - The default implementation emits the [classfnc]$messageClicked[/classfnc]() signal. - - - @signals: - !sg: $activated() - This signal is emitted by the default implementation of [classfnc]$activatedEvent[/classfnc]. - !sg: $messageClicked() - This signal is emitted by the default implementation of [classfnc]$messageClickedEvent[/classfnc]. -*/ - -KVSO_BEGIN_REGISTERCLASS(KviKvsObject_trayicon,"trayicon","object") - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_trayicon,show) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_trayicon,hide) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_trayicon,isVisible) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_trayicon,setIcon) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_trayicon,setTooltip) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_trayicon,showMessage) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_trayicon,setContextMenu) - // events - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_trayicon,activatedEvent) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_trayicon,messageClickedEvent) -KVSO_END_REGISTERCLASS(KviKvsObject_trayicon) - - -KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_trayicon,KviKvsObject) - m_pTrayIcon = new QSystemTrayIcon(0); - connect(m_pTrayIcon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(slotActivated(QSystemTrayIcon::ActivationReason))); - connect(m_pTrayIcon,SIGNAL(messageClicked()),this,SLOT(slotMessageClicked())); - -KVSO_END_CONSTRUCTOR(KviKvsObject_trayicon) - -KVSO_BEGIN_DESTRUCTOR(KviKvsObject_trayicon) - delete m_pTrayIcon; -KVSO_END_DESTRUCTOR(KviKvsObject_trayicon) - - -KVSO_CLASS_FUNCTION(trayicon,setIcon) -{ - CHECK_INTERNAL_POINTER(m_pTrayIcon) - QString szIcon; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("icon",KVS_PT_STRING,0,szIcon) - KVSO_PARAMETERS_END(c) - QPixmap * pix = g_pIconManager->getImage(szIcon); - if(pix) m_pTrayIcon->setIcon(*pix); - return true; -} -KVSO_CLASS_FUNCTION(trayicon,setTooltip) -{ - CHECK_INTERNAL_POINTER(m_pTrayIcon) - QString szTooltip; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("icon",KVS_PT_STRING,0,szTooltip) - KVSO_PARAMETERS_END(c) - m_pTrayIcon->setToolTip(szTooltip); - return true; -} -KVSO_CLASS_FUNCTION(trayicon,show) -{ - CHECK_INTERNAL_POINTER(m_pTrayIcon) - m_pTrayIcon->show(); - return true; -} -KVSO_CLASS_FUNCTION(trayicon,hide) -{ - CHECK_INTERNAL_POINTER(m_pTrayIcon) - m_pTrayIcon->show(); - return true; -} -KVSO_CLASS_FUNCTION(trayicon,isVisible) -{ - CHECK_INTERNAL_POINTER(m_pTrayIcon) - c->returnValue()->setBoolean(m_pTrayIcon->isVisible()); - return true; -} - -KVSO_CLASS_FUNCTION(trayicon,showMessage) -{ - CHECK_INTERNAL_POINTER(m_pTrayIcon) - QString szMessage,szTitle,szMessageIcon; - kvs_uint_t uTimeout; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("title",KVS_PT_STRING,0,szTitle) - KVSO_PARAMETER("message",KVS_PT_STRING,0,szMessage) - KVSO_PARAMETER("icon",KVS_PT_STRING,0,szMessageIcon) - KVSO_PARAMETER("timeout",KVS_PT_UINT,0,uTimeout) - KVSO_PARAMETERS_END(c) - QSystemTrayIcon::MessageIcon message=QSystemTrayIcon::NoIcon; - if(KviQString::equalCI(szMessageIcon,"NoIcon")) message= QSystemTrayIcon::NoIcon; - else if(KviQString::equalCI(szMessageIcon,"Information"))message= QSystemTrayIcon::Information; - else if(KviQString::equalCI(szMessageIcon,"Warning")) message= QSystemTrayIcon::Warning; - else if(KviQString::equalCI(szMessageIcon,"Critical")) message= QSystemTrayIcon::Critical; - else c->warning(__tr2qs_ctx("Invalid message Icon: switch to default NoIcon '%Q'","objects"),&szMessageIcon); - m_pTrayIcon->showMessage(szTitle,szMessage,message,uTimeout); - return true; -} - -KVSO_CLASS_FUNCTION(trayicon,setContextMenu) -{ - CHECK_INTERNAL_POINTER(m_pTrayIcon) - KviKvsObject *ob; - kvs_hobject_t hObject; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) - KVSO_PARAMETERS_END(c) - ob=KviKvsKernel::instance()->objectController()->lookupObject(hObject); - if (!ob) - { - c->warning(__tr2qs_ctx("Widget parameter is not an object","objects")); - return true; - } - if (!ob->object()) - { - c->warning(__tr2qs_ctx("Widget parameter is not a valid object","objects")); - return true; - } - if(!ob->inheritsClass("popupmenu")) - { - c->warning(__tr2qs_ctx("Can't add a non-popupmenu object","objects")); - return true; - } - m_pTrayIcon->setContextMenu(((QMenu *)(ob->object()))); - return true; -} -KVSO_CLASS_FUNCTION(trayicon,activatedEvent) -{ - emitSignal("activated",c,c->params()); - return true; -} -KVSO_CLASS_FUNCTION(trayicon,messageClickedEvent) -{ - emitSignal("messageClicked",c,c->params()); - return true; -} -void KviKvsObject_trayicon::slotMessageClicked() -{ - KviKvsVariantList *lParams=0; - callFunction(this,"messageClickedEvent",0,lParams); -} - -void KviKvsObject_trayicon::slotActivated(QSystemTrayIcon::ActivationReason reason) -{ - QString szReason; - if (reason==QSystemTrayIcon::Unknown) - szReason="Unknown"; - else if(reason==QSystemTrayIcon::Context) - szReason="Context"; - else if(reason==QSystemTrayIcon::DoubleClick) - szReason="DoubleClick"; - else if(reason==QSystemTrayIcon::Trigger) - szReason="Trigger"; - else szReason="MiddleClick"; - KviKvsVariantList lParams; - lParams.append(new KviKvsVariant(szReason)); - callFunction(this,"activatedEvent",0,&lParams); -} -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_class_trayicon.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/objects/class_trayicon.h b/src/modules/objects/class_trayicon.h deleted file mode 100644 index ea7f7d5b7..000000000 --- a/src/modules/objects/class_trayicon.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef _CLASS_TRAYICON_H_ -#define _CLASS_TRAYICON_H_ -//============================================================================= -// -// File : class_trayicon.h -// Creation date : Wed Ago 25 17:28:45 2010 GMT by Carbone Alesssandro -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2008 Alessandro Carbone (elfonol at gmail dot com) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - - - - -//=============================================================== -#include "object_macros.h" -#include -#include - -class KviKvsObject_trayicon : public KviKvsObject -{ - Q_OBJECT -public: - KVSO_DECLARE_OBJECT(KviKvsObject_trayicon) -protected: - QSystemTrayIcon *m_pTrayIcon; -protected: - bool setIcon(KviKvsObjectFunctionCall *c); - bool show(KviKvsObjectFunctionCall *c); - bool hide(KviKvsObjectFunctionCall *c); - bool isVisible(KviKvsObjectFunctionCall *c); - bool setTooltip(KviKvsObjectFunctionCall *c); - bool showMessage(KviKvsObjectFunctionCall *c); - bool setContextMenu(KviKvsObjectFunctionCall *c); - bool activatedEvent(KviKvsObjectFunctionCall *c); - bool messageClickedEvent(KviKvsObjectFunctionCall *c); - - -protected slots: - void slotActivated(QSystemTrayIcon::ActivationReason); - void slotMessageClicked(); -}; -#endif //_CLASS_TRAYICON_H_ diff --git a/src/modules/objects/class_treewidget.cpp b/src/modules/objects/class_treewidget.cpp deleted file mode 100644 index 5385df3da..000000000 --- a/src/modules/objects/class_treewidget.cpp +++ /dev/null @@ -1,666 +0,0 @@ -//============================================================================= -// -// File : class_treewidget.cpp -// Creation date : Fri Jan 28 14:21:48 CEST 2005 -// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2005-2008 Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "class_treewidget.h" - -#include "KviError.h" -#include "kvi_debug.h" -#include "KviLocale.h" -#include "KviIconManager.h" -#include - - #include - -#include -#include -#include -#include -#include - -/* - @doc: listview - @keyterms: - listview widget class - @title: - listview class - @type: - class - @short: - A listview widget class - @inherits: - [class]widget[/class] - @description: - It can display and control a hierarchy of multi-column items, and provides the ability to add new items at any time. - The items are added by creating children [class]listviewitem[/class] objects: simply allocating them with $new - will add the items to the listview and simply deleting them will remove them. - Allocating a [class]listviewtitem[/class] item2 as a child of item1 will insert it to the same listview creating - a subtree of items spannig from item1. The subtree can be opened or closed by a simple click either - on the parent item or on the little plus sign on the side of it (when [classfnc:listview]$setRootIsDecorated[/classfnc] - is set to $true. The listview can be in Single, Multi, Extended or NoSelection selection mode. - In single selection mode there can be only one selected item at a time and the selected item is also - the current item (this mode is the default). In Multi and Extended selection mode there can be multiple selected items - and the current item is one of them. The difference between Multi and Extended is in the way - that items can be selected by the mouse actions: experiment with the two modes :). - The NoSelection mode has obviously no selection at all. - @functions: - !fn: $addColumn(,[]) - Adds a width pixels wide column with the column header label to the list view. - - !fn: $setSorting(,) - Sets the list view to be sorted by column in ascending order if sort_order is "ascending" or descending order if it is "descending". - !fn: $setSortingEnabled() - If is true, user sorting is enabled for the tree. The default value is false. - In order to avoid performance issues, it is recommended that sorting is enabled after inserting the items into the tree. - !fn: $hideListViewHeader() - Hide the listview column header. - - !fn: $showListViewHeader() - Show the listview column header. - - !fn: $isListViewHeaderVisible() - Returns '1' if the listview header is currently visible. Otherwise this function returns '0'. - - !fn: $setAllColumnsShowFocus() - When the argument is $true, causes the listview to display the focus and selection - by highlighting all the columns of the item. When the argument is $false then - only the first column is selected/highlighted. - - !fn: $setSelectionMode() - Sets the selection mode for this listview. can be one of "Single","NoSelection","Multi" or "Extended". - - !fn: $selectedItems() - Returns the currently selected [class]listviewitem[/class] or $null if no items are selected. - This function works only if the list view is in single selection mode. - - !fn: $itemAt(,) - Returns the listviewitem object at the x,y globals coordinates or $null if no item at. - - !fn: $currentItem() - Returns the current [class]listviewitem[/class] or $null if no item is current at the moment. - - !fn: $firstChild() - Returns the first child [class]listviewitem[/class] of this listview or $null if there are no items at all. - - !fn: $topLevelItem() - Returns the child [class]listviewitem[/class] of this listview or $null if it does not exists. - - !fn: $topLevelItemCount() - Returns the number of top level items of this listview. - - !fn: setAcceptDrops() - If is true, user can drop files for this listview. The default value is true. - - !fn: $clickEvent() - This function is called when the user clicks in the list view. - In its argument the [class]listviewitem[/class] object clicked or 0 if the user didn't click on an item.[br] - The default implementation emits the [classfnc]$clicked[/classfnc]() signal. - - !fn: $selectionChangedEvent() - This event handle whenever the set of selected items has changed. - The argument is the newly selected item if the listview is in single selection mode.[br] - When the listview is in Multi or Extended selection mode then item is always $null.[br] - The default implementation emits the [classfnc]$selectionChanged[/classfnc]() signal. - - !fn: $currentChangedEvent() - This event are called whenever the current item has changed. - In its argument is the newly selected item or 0 if the change made no item current.[br] - The default implementation emits the [classfnc]$currentChanged[/classfnc]() signal. - - !fn: $itemActivatedEvent() - This s signal is emitted when the user activates an item by single- or double-clicking or pressing 'Enter'.[br] - In its argument the currrent item.[br] - The default implementation emits the [classfnc]$itemActivated[/classfnc]() signal. - - !fn: $spacePressedEvent() - This function is called by the framework when the space key is pressed.[br] - In its arument the currrent item.[br] - The default implementation emits the [classfnc]$spacePressed[/classfnc]() signal. - - !fn: $onItemEvent() - This event is called when an item has been expanded, i.e. when the children of item are shown. - The default implementation emits the [classfnc]$expanded[/classfnc]() signal. - - !fn: $itemCollapsedEvent() - This event is called when an item has been collapsed, i.e. when the children of item are hidden. - The default implementation emits the [classfnc]$collapsed[/classfnc]() signal. - - !fn: $itemChangedEvent(,,) - This event is called when the item has been renamed in text, e.g. by in in-place renaming, in column col.[br] - The default implementation emits the [classfnc]$itemChanged[/classfnc]() signal. - - - @signals: - !sg: $clicked() - This signal is emitted by the default implementation of [classfnc]$clickEvent[/classfnc](). - !sg: $selectionChanged() - This signal is emitted by the default implementation of [classfnc]$selectionChangedEvent[/classfnc](). - !sg: $currentChanged() - This signal is emitted by the default implementation of [classfnc]$currentChangedEvent[/classfnc](). - !sg: $itemActivated() - This signal is emitted by the default implementation of [classfnc]$itemActivatedEvent[/classfnc](). - !sg: $spacePressed() - This signal is emitted by the default implementation of [classfnc]$spacePredssedEvent[/classfnc](). - !sg: $onItem() - This signal is emitted by the default implementation of [classfnc]$onItemEvent[/classfnc](). - !sg: $itemExpanded() - This signal is emitted by the default implementation of [classfnc]$itemExpandedEvent[/classfnc](). - !sg: $itemCollapsed() - This signal is emitted by the default implementation of [classfnc]$itemCollapsedEvent[/classfnc](). - !sg: $itemChanged() - This signal is emitted by the default implementation of [classfnc]$itemChangedEvent[/classfnc](). - !sg: $rightButtonClicked() - This signal is emitted by the default implementation of [classfnc]$rightButtonClickedEvent[/classfnc](). - - -*/ - - - -//--------------------------------------------------------------------------------- - -KVSO_BEGIN_REGISTERCLASS(KviKvsObject_treewidget,"listview","widget") - - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,setHeaderLabels) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,addColumn) - - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,setColumnText) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,setColumnCount) - - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,setSorting) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,setSortingEnabled) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,setRootIsDecorated) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,setAllColumnsShowFocus) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,clear) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,selectedItems) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,currentItem) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,setSelectionMode) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,listViewHeaderIsVisible) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,itemAt) - - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,hideListViewHeader) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,showListViewHeader) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,firstChild) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,topLevelItem) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,topLevelItemCount) - - - - - //events - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,selectionChangedEvent); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,currentChangedEvent); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,itemActivatedEvent); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,onItemEvent); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,itemClickedEvent); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,itemExpandedEvent); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,itemCollapsedEvent); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,itemChangedEvent); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidget,setAcceptDrops); - KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_treewidget,"fileDroppedEvent") - -KVSO_END_REGISTERCLASS(KviKvsObject_treewidget) - -KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_treewidget,KviKvsObject_widget) - -KVSO_END_CONSTRUCTOR(KviKvsObject_treewidget) - - -KVSO_BEGIN_DESTRUCTOR(KviKvsObject_treewidget) - -KVSO_END_CONSTRUCTOR(KviKvsObject_treewidget) - -bool KviKvsObject_treewidget::init(KviKvsRunTimeContext *,KviKvsVariantList *) -{ - setObject(new KviKvsTreeWidget(parentScriptWidget(),getName().toUtf8().data(),this),true); - // hack for compatibility with "old" addColumn method; - ((QTreeWidget*) widget())->setColumnCount(0); - - connect(widget(),SIGNAL(itemClicked(QTreeWidgetItem *,int)),this,SLOT(slotClicked(QTreeWidgetItem *,int))); - connect(widget(),SIGNAL(itemSelectionChanged()),this,SLOT(slotSelectionChanged())); - connect(widget(),SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),this,SLOT(slotCurrentChanged(QTreeWidgetItem *,QTreeWidgetItem *))); - connect(widget(),SIGNAL(itemActivated(QTreeWidgetItem *,int)),this,SLOT(slotItemActivated(QTreeWidgetItem *,int))); - connect(widget(),SIGNAL(itemEntered(QTreeWidgetItem *,int)),this,SLOT(slotOnItemEntered(QTreeWidgetItem *,int))); - connect(widget(),SIGNAL(itemExpanded(QTreeWidgetItem *)),this,SLOT(slotItemExpanded(QTreeWidgetItem *))); - connect(widget(),SIGNAL(itemCollapsed(QTreeWidgetItem *)),this,SLOT(slotItemCollapsed(QTreeWidgetItem *))); - connect(widget(),SIGNAL(itemChanged(QTreeWidgetItem *,int)),this,SLOT(slotItemChanged(QTreeWidgetItem *,int))); - return true; -} - -KVSO_CLASS_FUNCTION(treewidget,setHeaderLabels) -{ - QStringList columns; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("labels",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,columns) - KVSO_PARAMETERS_END(c) - if (widget()){ - ((QTreeWidget *)object())->setHeaderLabels(columns); - } - return true; -} - -KVSO_CLASS_FUNCTION(treewidget,setColumnText) -{ - if (!widget()) return true; - QString szLabel; - kvs_int_t iCol; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("column",KVS_PT_INT,0,iCol) - KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel) - KVSO_PARAMETERS_END(c) - QTreeWidgetItem *header=((QTreeWidget *)widget())->headerItem(); - header->setText(iCol,szLabel); - return true; -} - -KVSO_CLASS_FUNCTION(treewidget,topLevelItem) -{ - if (!widget()) return true; - kvs_int_t iIdx; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("index",KVS_PT_INT,0,iIdx) - KVSO_PARAMETERS_END(c) - QTreeWidgetItem *pItem=((QTreeWidget *)widget())->topLevelItem(iIdx); - if (!pItem) c->returnValue()->setHObject((kvs_hobject_t)0); - else c->returnValue()->setHObject(KviKvsObject_treewidgetitem::itemToHandle(pItem)); - return true; -} -KVSO_CLASS_FUNCTION(treewidget,itemAt) -{ - if (!widget()) return true; - kvs_int_t iXpos,iYpos; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("x_pos",KVS_PT_INT,0,iXpos) - KVSO_PARAMETER("y_pos",KVS_PT_INT,0,iYpos) - KVSO_PARAMETERS_END(c) - QPoint pPoint=((QTreeWidget *)widget())->viewport()->mapFromGlobal(QPoint(iXpos,iYpos)); - QTreeWidgetItem *pItem=((QTreeWidget *)widget())->itemAt(pPoint); - if (!pItem) c->returnValue()->setHObject((kvs_hobject_t)0); - else c->returnValue()->setHObject(KviKvsObject_treewidgetitem::itemToHandle(pItem)); - return true; -} -KVSO_CLASS_FUNCTION(treewidget,topLevelItemCount) -{ - if (!widget()) return true; - c->returnValue()->setInteger(((QTreeWidget *)widget())->topLevelItemCount()); - return true; -} - -KVSO_CLASS_FUNCTION(treewidget,addColumn) -{ - if (!widget()) return true; - QString szLabel; - kvs_int_t iW; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel) - KVSO_PARAMETER("width",KVS_PT_INT,KVS_PF_OPTIONAL,iW) - KVSO_PARAMETERS_END(c) - int col=((QTreeWidget *)widget())->columnCount(); - QTreeWidgetItem *header=((QTreeWidget *)widget())->headerItem(); - header->setText(col,szLabel); - if(iW) ((QTreeWidget *)widget())->setColumnWidth(col,iW); - col++; - ((QTreeWidget *)widget())->setColumnCount(col); - //col++; - return true; -} - -KVSO_CLASS_FUNCTION(treewidget,setAcceptDrops) -{ - bool bEnable; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("bEnable",KVS_PT_BOOLEAN,0,bEnable) - KVSO_PARAMETERS_END(c) - if (widget()) - ((QTreeWidget *)object())->setAcceptDrops(bEnable); - return true; -} - -KVSO_CLASS_FUNCTION(treewidget,clear) -{ - Q_UNUSED(c); - if (widget()) - ((QTreeWidget *)object())->clear(); - return true; -} - -KVSO_CLASS_FUNCTION(treewidget,selectedItems) -{ - if(widget()) - { - QList list=((QTreeWidget *)widget())->selectedItems(); - KviKvsArray * pArray = new KviKvsArray(); - c->returnValue()->setArray(pArray); - for (int i=0;iset(i,new KviKvsVariant(KviKvsObject_treewidgetitem::itemToHandle((QTreeWidgetItem*)list.at(i)))); - } - else - c->returnValue()->setHObject((kvs_hobject_t)0); - return true; -} - -KVSO_CLASS_FUNCTION(treewidget,firstChild) -{ - if(widget()) - c->returnValue()->setHObject(KviKvsObject_treewidgetitem::itemToHandle((QTreeWidgetItem*)((QTreeWidget *)widget())->topLevelItem(0))); - else - c->returnValue()->setHObject((kvs_hobject_t)0); - return true; -} - -KVSO_CLASS_FUNCTION(treewidget,currentItem) -{ - if(widget()) - c->returnValue()->setHObject(KviKvsObject_treewidgetitem::itemToHandle((QTreeWidgetItem*)((QTreeWidget *)widget())->currentItem())); - else - c->returnValue()->setHObject((kvs_hobject_t)0); - return true; -} -/* -KVSO_CLASS_FUNCTION(treewidget,setColumnText) -{ - kvs_int_t uCol; - QString szText; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) - KVSO_PARAMETERS_END(c) - if (widget())((QTreeWidget *)widget())->setColumnText(uCol,szText); - return true; -} -*/ -KVSO_CLASS_FUNCTION(treewidget,setColumnCount) -{ - kvs_uint_t uCol; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETERS_END(c) - if (widget())((QTreeWidget *)widget())->setColumnCount(uCol); - return true; -} - -KVSO_CLASS_FUNCTION(treewidget,setSelectionMode) -{ - QString szMode; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("mode",KVS_PT_NONEMPTYSTRING,0,szMode) - KVSO_PARAMETERS_END(c) - if(!widget())return true; - if(KviQString::equalCI(szMode,"NoSelection")) - ((QTreeWidget *)widget())->setSelectionMode(QAbstractItemView::NoSelection); - else if(KviQString::equalCI(szMode,"Multi")) - ((QTreeWidget *)widget())->setSelectionMode(QTreeWidget::MultiSelection); - else if(KviQString::equalCI(szMode,"Extended")) - ((QTreeWidget *)widget())->setSelectionMode(QTreeWidget::ExtendedSelection); - else if(KviQString::equalCI(szMode,"Single")) - ((QTreeWidget *)widget())->setSelectionMode(QTreeWidget::SingleSelection); - else c->warning(__tr2qs_ctx("Invalid selection mode '%Q'","objects"),&szMode); - return true; -} - -KVSO_CLASS_FUNCTION(treewidget,setSorting) -{ - kvs_int_t iCol; - QString szOrder; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("column",KVS_PT_INT,0,iCol) - KVSO_PARAMETER("sort_order",KVS_PT_STRING,0,szOrder) - KVSO_PARAMETERS_END(c) - if (!widget())return true; - if (KviQString::equalCI(szOrder,"ascending")) ((QTreeWidget *)widget())->sortItems(iCol,Qt::AscendingOrder); - else if (KviQString::equalCI(szOrder,"descending")) ((QTreeWidget *)widget())->sortItems(iCol,Qt::DescendingOrder); - else c->warning(__tr2qs_ctx("Unknown '%Q' sort order: switching to ascending order","objects"),&szOrder); - return true; -} -KVSO_CLASS_FUNCTION(treewidget,setSortingEnabled) -{ - bool bEnables; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("bEnables",KVS_PT_BOOLEAN,0,bEnables) - KVSO_PARAMETERS_END(c) - if (!widget())return true; - ((QTreeWidget *)widget())->setSortingEnabled(bEnables); - return true; -} - -KVSO_CLASS_FUNCTION(treewidget,setRootIsDecorated) -{ - bool bEnabled; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) - KVSO_PARAMETERS_END(c) - if (widget()) ((QTreeWidget *)widget())->setRootIsDecorated(bEnabled); - return true; -} - -KVSO_CLASS_FUNCTION(treewidget,setAllColumnsShowFocus) -{ - bool bEnabled; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("bAllColumnsShowFocus",KVS_PT_BOOL,0,bEnabled) - KVSO_PARAMETERS_END(c) - if (widget())((QTreeWidget *)widget())->setAllColumnsShowFocus(bEnabled); - return true; -} - -KVSO_CLASS_FUNCTION(treewidget,hideListViewHeader) -{ - Q_UNUSED(c); - ((QTreeWidget *)widget())->header()->hide(); - return true; -} - -KVSO_CLASS_FUNCTION(treewidget,showListViewHeader) -{ - Q_UNUSED(c); - ((QTreeWidget *)widget())->header()->show(); - return true; -} - -KVSO_CLASS_FUNCTION(treewidget,listViewHeaderIsVisible) -{ - c->returnValue()->setBoolean(((QTreeWidget *)widget())->header()->isVisible()); - return true; -} - -KVSO_CLASS_FUNCTION(treewidget,itemClickedEvent) -{ - emitSignal("itemClicked",c,c->params()); - return true; -} - -void KviKvsObject_treewidget::slotClicked(QTreeWidgetItem * i,int col) -{ - KviKvsVariant *column=new KviKvsVariant((kvs_int_t)col); - - KviKvsVariantList params(new KviKvsVariant(KviKvsObject_treewidgetitem::itemToHandle(i)),column); - callFunction(this,"itemClickedEvent",0,¶ms); -} - -KVSO_CLASS_FUNCTION(treewidget,selectionChangedEvent) -{ - emitSignal("selectionChanged",c,c->params()); - return true; -} - -void KviKvsObject_treewidget::slotSelectionChanged() -{ - if (((QTreeWidget *)widget())->selectionMode()==QTreeWidget::SingleSelection) - { - QTreeWidgetItem *it=(QTreeWidgetItem *) ((QTreeWidget *)widget())->currentItem(); - KviKvsVariantList params(new KviKvsVariant(KviKvsObject_treewidgetitem::itemToHandle(it))); - callFunction(this,"selectionChangedEvent",0,¶ms); - } - else{ - KviKvsVariantList params(new KviKvsVariant((kvs_hobject_t)0)); - callFunction(this,"selectionChangedEvent",0,¶ms); - } -} - -KVSO_CLASS_FUNCTION(treewidget,currentChangedEvent) -{ - emitSignal("currentChanged",c,c->params()); - return true; -} - -void KviKvsObject_treewidget::slotCurrentChanged(QTreeWidgetItem * i,QTreeWidgetItem *prev) -{ - KviKvsVariantList params(new KviKvsVariant(KviKvsObject_treewidgetitem::itemToHandle(i)),new KviKvsVariant(KviKvsObject_treewidgetitem::itemToHandle(prev))); - callFunction(this,"currentChangedEvent",0,¶ms); -} - -KVSO_CLASS_FUNCTION(treewidget,itemActivatedEvent) -{ - emitSignal("itemActivated",c,c->params()); - return true; -} - -void KviKvsObject_treewidget::slotItemActivated(QTreeWidgetItem * i,int col) -{ - KviKvsVariant *column=new KviKvsVariant((kvs_int_t)col); - KviKvsVariantList params(new KviKvsVariant(KviKvsObject_treewidgetitem::itemToHandle(i)),column); - callFunction(this,"itemActivatedEvent",0,¶ms); -} - -KVSO_CLASS_FUNCTION(treewidget,onItemEvent) -{ - - emitSignal("onItem",c,c->params()); - return true; -} - -void KviKvsObject_treewidget::slotOnItemEntered(QTreeWidgetItem * i,int col) -{ - KviKvsVariant *column=new KviKvsVariant((kvs_int_t)col); - - KviKvsVariantList params(new KviKvsVariant(KviKvsObject_treewidgetitem::itemToHandle(i)),column); - callFunction(this,"onItemEvent",0,¶ms); -} - -KVSO_CLASS_FUNCTION(treewidget,itemExpandedEvent) -{ - emitSignal("itemExpanded",c,c->params()); - return true; -} - -void KviKvsObject_treewidget::slotItemExpanded(QTreeWidgetItem * i) -{ - KviKvsVariantList params(new KviKvsVariant(KviKvsObject_treewidgetitem::itemToHandle(i))); - callFunction(this,"itemExpandedEvent",0,¶ms); -} - -KVSO_CLASS_FUNCTION(treewidget,itemCollapsedEvent) -{ - emitSignal("itemCollapsed",c,c->params()); - return true; -} - -void KviKvsObject_treewidget::slotItemCollapsed(QTreeWidgetItem * i) -{ - KviKvsVariantList params(new KviKvsVariant(KviKvsObject_treewidgetitem::itemToHandle(i))); - callFunction(this,"itemCollapsedEvent",0,¶ms); -} - - - -KVSO_CLASS_FUNCTION(treewidget,itemChangedEvent) -{ - emitSignal("itemChanged",c,c->params()); - return true; -} - -void KviKvsObject_treewidget::slotItemChanged(QTreeWidgetItem *item,int col) -{ - KviKvsVariant *column=new KviKvsVariant((kvs_int_t)col); - KviKvsVariantList params(new KviKvsVariant(KviKvsObject_treewidgetitem::itemToHandle(item)),column); - callFunction(this,"itemChangedEvent",0,¶ms); -} - -void KviKvsObject_treewidget::fileDropped(QString &szFile,QTreeWidgetItem *item) -{ - KviKvsVariant *file=new KviKvsVariant(szFile); - KviKvsVariantList params(new KviKvsVariant(KviKvsObject_treewidgetitem::itemToHandle(item)),file); - callFunction(this,"fileDroppedEvent",0,¶ms); -} - -KviKvsTreeWidget::KviKvsTreeWidget(QWidget * par,const char *,KviKvsObject_treewidget *parent) -:QTreeWidget(par) -{ - m_pParentScript=parent; - setAcceptDrops(true); - setDragEnabled(true); - setDropIndicatorShown(true); - setDragDropMode(QAbstractItemView::DragDrop); - viewport()->setAcceptDrops(true); -} - -KviKvsTreeWidget::~KviKvsTreeWidget() -{ -} - -void KviKvsTreeWidget::dragEnterEvent( QDragEnterEvent * e ) -{ - if(!e->mimeData()->hasUrls()) - { - e->ignore(); - return; - } - e->acceptProposedAction(); -} - -void KviKvsTreeWidget::dragMoveEvent( QDragMoveEvent * ) -{ - // ?#! -} - -void KviKvsTreeWidget::dropEvent(QDropEvent * e) -{ - qDebug("Drop event"); - QList list; - if(e->mimeData()->hasUrls()) - { - list = e->mimeData()->urls(); - - if(!list.isEmpty()) - { - QList::Iterator it = list.begin(); - for( ; it != list.end(); ++it ) - { - QUrl url = *it; - QString path = url.toLocalFile(); - qDebug("path %s",path.toUtf8().data()); - QTreeWidgetItem *i = itemAt( e->pos() ); - m_pParentScript->fileDropped(path,i); - } - } - } -} - -#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES -#include "m_class_treewidget.moc" -#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES diff --git a/src/modules/objects/class_treewidget.h b/src/modules/objects/class_treewidget.h deleted file mode 100644 index 579bce997..000000000 --- a/src/modules/objects/class_treewidget.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef _CLASS_TREEWIDGET_H_ -#define _CLASS_TREEWIDGET_H_ -//============================================================================= -// -// File : class_treewidget.h -// Creation date : Fri Jan 28 14:21:48 CEST 2005 -// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2005-2008 Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "class_widget.h" -#include "class_treewidgetitem.h" -#include "object_macros.h" - -#include - -class KviKvsObject_treewidget : public KviKvsObject_widget -{ - Q_OBJECT -public: - KVSO_DECLARE_OBJECT(KviKvsObject_treewidget) - -public: - QWidget * widget() { return (QWidget *)object(); }; - void fileDropped(QString &,QTreeWidgetItem *); -protected: - virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); - - bool addColumn(KviKvsObjectFunctionCall *c); - bool setColumnText(KviKvsObjectFunctionCall *c); - bool takeItem(KviKvsObjectFunctionCall *c); - bool setSorting(KviKvsObjectFunctionCall *c); - bool setSortingEnabled(KviKvsObjectFunctionCall *c); - bool setRootIsDecorated(KviKvsObjectFunctionCall *c); - bool clear(KviKvsObjectFunctionCall *c); - bool setAllColumnsShowFocus(KviKvsObjectFunctionCall *c); - bool itemClickedEvent(KviKvsObjectFunctionCall *c); - bool selectionChangedEvent(KviKvsObjectFunctionCall *c); - bool currentChangedEvent(KviKvsObjectFunctionCall *c); - bool itemActivatedEvent(KviKvsObjectFunctionCall *c); - bool onItemEvent(KviKvsObjectFunctionCall *c); - bool itemExpandedEvent(KviKvsObjectFunctionCall *c); - bool itemCollapsedEvent(KviKvsObjectFunctionCall *c); - bool itemChangedEvent(KviKvsObjectFunctionCall *c); - bool selectedItems(KviKvsObjectFunctionCall *c); - bool currentItem(KviKvsObjectFunctionCall *c); - bool setSelectionMode(KviKvsObjectFunctionCall *c); - bool firstChild(KviKvsObjectFunctionCall *c); - bool listViewHeaderIsVisible(KviKvsObjectFunctionCall *c); - bool showListViewHeader(KviKvsObjectFunctionCall *c); - bool hideListViewHeader(KviKvsObjectFunctionCall *c); - bool setAcceptDrops(KviKvsObjectFunctionCall *c); - bool setHeaderLabels(KviKvsObjectFunctionCall *c); - bool setColumnCount(KviKvsObjectFunctionCall *c); - bool topLevelItem(KviKvsObjectFunctionCall *c); - bool topLevelItemCount(KviKvsObjectFunctionCall *c); - bool itemAt(KviKvsObjectFunctionCall *c); -protected slots: - void slotClicked(QTreeWidgetItem *,int); - void slotSelectionChanged(); - void slotCurrentChanged(QTreeWidgetItem *,QTreeWidgetItem *); - void slotItemActivated(QTreeWidgetItem *,int col); - void slotOnItemEntered(QTreeWidgetItem *,int col); - void slotItemExpanded(QTreeWidgetItem *); - void slotItemCollapsed(QTreeWidgetItem *); - void slotItemChanged(QTreeWidgetItem *,int); -}; - -class KviKvsTreeWidget : public QTreeWidget -{ - Q_OBJECT -public: - KviKvsTreeWidget(QWidget * par, const char * name, KviKvsObject_treewidget *); - virtual ~KviKvsTreeWidget(); -protected: - KviKvsObject_treewidget * m_pParentScript; -protected: - void dropEvent(QDropEvent * e); - void dragEnterEvent(QDragEnterEvent * e); - void dragMoveEvent( QDragMoveEvent * e ); -}; - -#endif // _CLASS_TREEWIDGET_H_ diff --git a/src/modules/objects/class_treewidgetitem.cpp b/src/modules/objects/class_treewidgetitem.cpp deleted file mode 100644 index e9ac48c1a..000000000 --- a/src/modules/objects/class_treewidgetitem.cpp +++ /dev/null @@ -1,429 +0,0 @@ -//============================================================================= -// -// File : class_treewidgetitem.cpp -// Creation date : Fri Jan 28 14:21:48 CEST 2005 -// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2005-2008 Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "class_treewidgetitem.h" -#include "class_pixmap.h" - -#include "KviError.h" -#include "kvi_debug.h" -#include "KviLocale.h" -#include "KviIconManager.h" -#include - -const int item_flags[] = { - Qt::NoItemFlags, - Qt::ItemIsSelectable, - Qt::ItemIsEditable, - Qt::ItemIsDragEnabled, - Qt::ItemIsDropEnabled, - Qt::ItemIsUserCheckable, - Qt::ItemIsEnabled, - Qt::ItemIsTristate -}; - -const char * const itemflags_tbl[] = { - "noitemflag", - "selectable", - "editable", - "dragEnabled", - "dropEnabled", - "userCheckable", - "enabled", - "tristate" -}; - -#define itemflags_num (sizeof(itemflags_tbl) / sizeof(itemflags_tbl[0])) - - - -/* - @doc: listviewitem - @keyterms: - listview tlistviewitem class - @title: - listviewtitem class - @type: - class - @short: - A listviewitem class - @inherits: - [class]listviewitem[/class] - @description: - The listviewitem class implements a list view item. - A list view item is a multi-column object capable of displaying itself in a [class]listview[/class]. - To use this class you must instantiate it with another listviewitem or a [class]listview[/class] - as parent. The item will be automatically displayed. - You can set the text and a pixmap in each column and you can make it checkable - with [classfnc:listviewitem]$setCheckable[/classfnc](). - A checkable listviewitem will display a small check mark in the first column. - @functions: - !fn: $setText(,) - Sets the text in column column to text, if column is a valid column number and text is different from the existing text. - - !fn: $text() - Returs the text of the specified column. - - !fn: $setPixmap(,) - Sets the pixmap in column column to pm, if pm is non-null and different from the current pixmap, and if column is non-negative. - Pixmap can be a Kvirc imageid, an image file or a [class]pixmap[/class] object. - - !fn: $setItemEditable() - If bEnabled is TRUE (1), this item can be in-place editable by the user; otherwise it cannot be editable in-place. - - !fn: $isItemEditable() - Returns $true if this item is editable and $false otherwise. - - !fn: $setEnabled() - Enables or disables the item. - - !fn: $isEnabled() - Returns $true if this item is enabled and $false otherwise. - - !fn: $setOpen() - Opens or closes the item to show its children items. - - !fn: $isOpen() - Returns the open state of this item - - !fn: $setCheckable() - Makes this item checkable or not. This function should be called immediately - after the item creation: changing this property later at runtime may have - strange results (like the item being moved inside the list, text disappearing, - hidden children etc... don't do it :D ). - - !fn: $isCheckable() - Returns $true if this item is checkable and $false otherwise - - !fn: $setChecked() - Sets this item to be checked or not. [classfnc:listviewitem]$setCheckable[/classfnc]() must - have been previously called. - - !fn: $isChecked() - Returns the check status of this item. [classfnc:listviewitem]$setCheckable[/classfnc]() must - have been previously called. - - !fn: $setFlags(, , ...) - Sets the flags for the item to the given flags. These determine whether the item can be selected or modified. This is often used to disable an item. - Supported flags are: - - noitemflag : no flag sets; - - selectable : item is selecatble; - - editable : item is editable; - - dragEnabled : item can dragged; - - dropEnabled : item can used as drop target; - - userCheckable : item is checkable; - - enabled :item is enabled; - - tristate : item is checkable with three separate states. - - -*/ - - -//=========================================================================================== - -KVSO_BEGIN_REGISTERCLASS(KviKvsObject_treewidgetitem,"listviewitem","object") - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidgetitem,setText) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidgetitem,text) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidgetitem,setPixmap); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidgetitem,setItemEditable); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidgetitem,isItemEditable); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidgetitem,setEnabled); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidgetitem,isEnabled); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidgetitem,setOpen); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidgetitem,isOpen); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidgetitem,setCheckable); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidgetitem,isCheckable); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidgetitem,setChecked); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidgetitem,isChecked); - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_treewidgetitem,setFlags); - -KVSO_END_REGISTERCLASS(KviKvsObject_treewidgetitem) - - -KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_treewidgetitem,KviKvsObject) - - m_pTreeWidgetItem = 0; - -KVSO_END_CONSTRUCTOR(KviKvsObject_treewidgetitem) - - -KVSO_BEGIN_DESTRUCTOR(KviKvsObject_treewidgetitem) - - if(m_pTreeWidgetItem)delete m_pTreeWidgetItem; - -KVSO_END_CONSTRUCTOR(KviKvsObject_treewidgetitem) - -bool KviKvsObject_treewidgetitem::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *) -{ - if (!parentObject()) - { - pContext->error(__tr2qs_ctx("The listviewitem cannot be parentless","objects")); - return false; - } - if(parentObject()->inheritsClass("listviewitem")) - { - m_pTreeWidgetItem = new KviKvsStandardTreeWidgetItem(this,((KviKvsObject_treewidgetitem *)parentObject())->m_pTreeWidgetItem); - } else { - if(parentObject()->inheritsClass("listview")) - m_pTreeWidgetItem = new KviKvsStandardTreeWidgetItem(this,((QTreeWidget *)parentScriptWidget())); - else { - pContext->error(__tr2qs_ctx("The parent of the listviewitem must be either another listviewitem or a listview","objects")); - return false; - } - } - return true; -} - -void KviKvsObject_treewidgetitem::childDestroyed() -{ - if(m_pTreeWidgetItem == 0)return; - m_pTreeWidgetItem = 0; - die(); -} - -KviKvsStandardTreeWidgetItem::KviKvsStandardTreeWidgetItem(KviKvsObject_treewidgetitem * ob,QTreeWidget * par) -:QTreeWidgetItem(par), m_pMasterObject(ob) -{ -} - -KviKvsStandardTreeWidgetItem::KviKvsStandardTreeWidgetItem(KviKvsObject_treewidgetitem * ob,QTreeWidgetItem * par) -:QTreeWidgetItem(par), m_pMasterObject(ob) -{ -} - -KviKvsStandardTreeWidgetItem::~KviKvsStandardTreeWidgetItem() -{ - if(m_pMasterObject)m_pMasterObject->childDestroyed(); -} - -kvs_hobject_t KviKvsObject_treewidgetitem::itemToHandle(QTreeWidgetItem * it) -{ - if(!it)return (kvs_hobject_t)0; - KviKvsObject_treewidgetitem * pObject; - pObject = ((KviKvsStandardTreeWidgetItem *)it)->masterObject(); - if(!pObject)return (kvs_hobject_t)0; - return pObject->handle(); -} - -KVSO_CLASS_FUNCTION(treewidgetitem,setText) -{ - kvs_uint_t uCol; - QString szText; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETER("text",KVS_PT_STRING,0,szText) - KVSO_PARAMETERS_END(c) - if(m_pTreeWidgetItem) - m_pTreeWidgetItem->setText(uCol,szText); - return true; -} - - -KVSO_CLASS_FUNCTION(treewidgetitem,setItemEditable) -{ - bool bEnabled; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) - KVSO_PARAMETERS_END(c) - if(m_pTreeWidgetItem) - m_pTreeWidgetItem->setFlags(bEnabled?m_pTreeWidgetItem->flags()|Qt::ItemIsEditable:m_pTreeWidgetItem->flags()&~Qt::ItemIsEditable); - return true; -} -KVSO_CLASS_FUNCTION(treewidgetitem,isItemEditable) -{ - if(!m_pTreeWidgetItem) - { - c->returnValue()->setBoolean(false); - return true; - } - c->returnValue()->setBoolean(m_pTreeWidgetItem->flags()&Qt::ItemIsEditable); - return true; -} -KVSO_CLASS_FUNCTION(treewidgetitem,setFlags) -{ - QStringList itemflags; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("flags",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,itemflags) - KVSO_PARAMETERS_END(c) - int flag,sum=0; - for ( int i=0;isetCheckState(0,Qt::Unchecked); - sum = sum | flag; - } - else - c->warning(__tr2qs_ctx("Unknown item flag '%Q'","objects"),&itemflags.at(i)); - } - if(m_pTreeWidgetItem) - m_pTreeWidgetItem->setFlags((Qt::ItemFlags)sum); - - return true; -} - -KVSO_CLASS_FUNCTION(treewidgetitem,setEnabled) -{ - bool bEnabled; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) - KVSO_PARAMETERS_END(c) - if(m_pTreeWidgetItem) - m_pTreeWidgetItem->setFlags(bEnabled?m_pTreeWidgetItem->flags()|Qt::ItemIsEnabled:m_pTreeWidgetItem->flags()&~Qt::ItemIsEnabled); - return true; -} - -KVSO_CLASS_FUNCTION(treewidgetitem,isEnabled) -{ - if(!m_pTreeWidgetItem) - { - c->returnValue()->setBoolean(false); - return true; - } - c->returnValue()->setBoolean(m_pTreeWidgetItem->flags()&Qt::ItemIsEnabled); - return true; -} - -KVSO_CLASS_FUNCTION(treewidgetitem,setOpen) -{ - bool bEnabled; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) - KVSO_PARAMETERS_END(c) - if(m_pTreeWidgetItem) - m_pTreeWidgetItem->setExpanded(bEnabled); - return true; -} - -KVSO_CLASS_FUNCTION(treewidgetitem,isOpen) -{ - if(!m_pTreeWidgetItem) - { - c->returnValue()->setBoolean(false); - return true; - } - c->returnValue()->setBoolean(m_pTreeWidgetItem->isExpanded()); - return true; -} - -KVSO_CLASS_FUNCTION(treewidgetitem,setChecked) -{ - bool bChecked; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("bChecked",KVS_PT_BOOL,0,bChecked) - KVSO_PARAMETERS_END(c) - if(!m_pTreeWidgetItem)return true; - ((QTreeWidgetItem *)m_pTreeWidgetItem)->setCheckState(0,bChecked?Qt::Checked:Qt::Unchecked); - return true; -} - -KVSO_CLASS_FUNCTION(treewidgetitem,isChecked) -{ - if(!m_pTreeWidgetItem) - { - c->returnValue()->setBoolean(false); - return true; - } - c->returnValue()->setBoolean(((QTreeWidgetItem *)m_pTreeWidgetItem)->checkState(0)==Qt::Checked?1:0); - return true; -} - -KVSO_CLASS_FUNCTION(treewidgetitem,setCheckable) -{ - bool bEnabled; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("bCheckable",KVS_PT_BOOL,0,bEnabled) - KVSO_PARAMETERS_END(c) - if(!m_pTreeWidgetItem)return true; - m_pTreeWidgetItem->setFlags(bEnabled?m_pTreeWidgetItem->flags()|Qt::ItemIsUserCheckable:m_pTreeWidgetItem->flags()&~Qt::ItemIsUserCheckable); - return true; -} - -KVSO_CLASS_FUNCTION(treewidgetitem,isCheckable) -{ - if(!m_pTreeWidgetItem) - { - c->returnValue()->setBoolean(false); - return true; - } - c->returnValue()->setBoolean(m_pTreeWidgetItem->flags()&Qt::ItemIsUserCheckable); - return true; -} - -KVSO_CLASS_FUNCTION(treewidgetitem,text) -{ - kvs_uint_t uCol; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETERS_END(c) - if(m_pTreeWidgetItem) - c->returnValue()->setString(m_pTreeWidgetItem->text(uCol)); - return true; -} - -KVSO_CLASS_FUNCTION(treewidgetitem,setPixmap) -{ - kvs_uint_t uCol; - KviKvsObject *obPixmap; - kvs_hobject_t obHpixmap; - KviKvsVariant * vPixmap; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETER("pixmap",KVS_PT_VARIANT,0,vPixmap) - KVSO_PARAMETERS_END(c) - QPixmap *pix = 0; - if (vPixmap->isEmpty()) {m_pTreeWidgetItem->setIcon(uCol,QIcon());return true;} - if(vPixmap->isHObject()) - { - vPixmap->asHObject(obHpixmap); - obPixmap=KviKvsKernel::instance()->objectController()->lookupObject(obHpixmap); - if (!obPixmap->inheritsClass("pixmap")) - { - c->warning(__tr2qs_ctx("Pixmap object or image Id required","objects")); - return true; - } - pix=((KviKvsObject_pixmap *)obPixmap)->getPixmap(); - } else { - QString szPix; - vPixmap->asString(szPix); - pix=g_pIconManager->getImage(szPix); - if(!pix) - { - c->warning(__tr2qs_ctx("Error occured: the suitable file '%Q' is not of the correct format or it is not a valid icon number.","objects"),&szPix); - return true; - } - } - m_pTreeWidgetItem->setIcon(uCol,QIcon(*pix)); - return true; -} - diff --git a/src/modules/objects/class_treewidgetitem.h b/src/modules/objects/class_treewidgetitem.h deleted file mode 100644 index 8700232d2..000000000 --- a/src/modules/objects/class_treewidgetitem.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef _CLASS_TREEWIDGETITEM_H_ -#define _CLASS_TREEWIDGETITEM_H_ -//============================================================================= -// -// File : class_treewidgetitem.h -// Creation date : Fri Jan 28 14:21:48 CEST 2005 -// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2005-2008 Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - - -#include "class_widget.h" -#include "object_macros.h" - -#include - -class KviKvsObject_treewidgetitem : public KviKvsObject -{ -public: - KVSO_DECLARE_OBJECT(KviKvsObject_treewidgetitem) - void childDestroyed(); -protected: - QTreeWidgetItem * m_pTreeWidgetItem; -protected: - virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); -protected: - bool setText(KviKvsObjectFunctionCall *c); - bool insertItem(KviKvsObjectFunctionCall *c); - bool setPixmap(KviKvsObjectFunctionCall *c); - bool setItemEditable(KviKvsObjectFunctionCall *c); - bool isItemEditable(KviKvsObjectFunctionCall *c); - bool setEnabled(KviKvsObjectFunctionCall *c); - bool isEnabled(KviKvsObjectFunctionCall *c); - bool setOpen(KviKvsObjectFunctionCall *c); - bool isOpen(KviKvsObjectFunctionCall *c); - bool text(KviKvsObjectFunctionCall *c); - bool setCheckable(KviKvsObjectFunctionCall *c); - bool isCheckable(KviKvsObjectFunctionCall *c); - bool setChecked(KviKvsObjectFunctionCall *c); - bool isChecked(KviKvsObjectFunctionCall *c); - bool setFlags(KviKvsObjectFunctionCall *c); - -public: - static kvs_hobject_t itemToHandle(QTreeWidgetItem * it); -}; - - -class KviKvsStandardTreeWidgetItem : public QTreeWidgetItem -{ -public: - KviKvsStandardTreeWidgetItem(KviKvsObject_treewidgetitem * ob,QTreeWidget * par); - KviKvsStandardTreeWidgetItem(KviKvsObject_treewidgetitem * ob,QTreeWidgetItem * par); - virtual ~KviKvsStandardTreeWidgetItem(); -protected: - KviKvsObject_treewidgetitem * m_pMasterObject; -public: - KviKvsObject_treewidgetitem * masterObject(){ return m_pMasterObject; } -}; - - -#endif // _CLASS_TREEWIDGETITEM_H_ diff --git a/src/modules/objects/class_vbox.cpp b/src/modules/objects/class_vbox.cpp deleted file mode 100644 index b2f6251a7..000000000 --- a/src/modules/objects/class_vbox.cpp +++ /dev/null @@ -1,209 +0,0 @@ -//============================================================================= -// -// File : class_vbox.cpp -// Creation date : Fri Mar 18 14:30:48 CEST 2005 -// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#define _KVI_DEBUG_CHECK_RANGE_ -#include "kvi_debug.h" -#include "KviLocale.h" - -#include "class_vbox.h" - -#include "KviTalVBox.h" - - -// Tables used in $setAlignment & $alignment -const char * const align_tbl[] = { - "Left", - "Right", - "HCenter", - "VCenter", - "Center", - "Top", - "Bottom", - "WordBreak" - }; - - - -const int align_cod[] = { - Qt::AlignLeft, - Qt::AlignRight, - Qt::AlignHCenter, - Qt::AlignVCenter, - Qt::AlignCenter, - Qt::AlignTop, - Qt::AlignBottom, - Qt::AlignJustify, - }; - -#define align_num (sizeof(align_tbl) / sizeof(align_tbl[0])) -/* - @doc: vbox - @keyterms: - vbox object class, child widgets - @title: - vbox class - @type: - class - @short: - Manages child widget vertical geometry - @inherits: - [class]object[/class] - @description: - The vbox class widget provides vertical geometry management for its child widgets. - @functions: - !fn: $setSpacing() - Sets the default spacing of the widgets in pixels - !fn: $setMargin() - Sets the dimension of the layout margin : the distance from the border to the outermost child widget edges. - !fn: $setStretchFactor(,) - Sets the stretch factor of widget to stretch. - !fn: $addStretch() - Adds a stretchable space with zero minimum size and stretch factor stretch to the end of this box layout. - !fn: $setAlignment(, , ...) - Sets the alignment for widget w to flags, given as parameters. - Valid flags are:Right,Left,Top,Bottom,HCenter,VCenter,Center -*/ - - -KVSO_BEGIN_REGISTERCLASS(KviKvsObject_vbox,"vbox","widget") - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_vbox,setMargin) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_vbox,setSpacing) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_vbox,setStretchFactor) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_vbox,addStretch) - KVSO_REGISTER_HANDLER_BY_NAME(KviKvsObject_vbox,setAlignment) -KVSO_END_REGISTERCLASS(KviKvsObject_vbox) - -KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_vbox,KviKvsObject_widget) - -KVSO_END_CONSTRUCTOR(KviKvsObject_vbox) - - -KVSO_BEGIN_DESTRUCTOR(KviKvsObject_vbox) - -KVSO_END_CONSTRUCTOR(KviKvsObject_vbox) - -bool KviKvsObject_vbox::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams) -{ - Q_UNUSED(pContext); - Q_UNUSED(pParams); - - SET_OBJECT(KviTalVBox); - return true; -} - -KVSO_CLASS_FUNCTION(vbox,setMargin) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_int_t iMargin; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("margin",KVS_PT_INT,0,iMargin) - KVSO_PARAMETERS_END(c) - ((KviTalVBox *)widget())->setMargin(iMargin); - return true; -} - -KVSO_CLASS_FUNCTION(vbox,setSpacing) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_int_t iSpacing; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("spacing",KVS_PT_INT,0,iSpacing) - KVSO_PARAMETERS_END(c) - ((KviTalVBox *)widget())->setSpacing(iSpacing); - return true; -} - -KVSO_CLASS_FUNCTION(vbox,setStretchFactor) -{ - CHECK_INTERNAL_POINTER(widget()) - KviKvsObject * pObject; - kvs_hobject_t hObject; - kvs_uint_t uStretch; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) - KVSO_PARAMETER("stretch",KVS_PT_UNSIGNEDINTEGER,0,uStretch) - KVSO_PARAMETERS_END(c) - pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); - return true; - CHECK_HOBJECT_IS_WIDGET(pObject) - if(((KviKvsObject_widget *)pObject)->widget()->parentWidget() != widget()) - { - c->warning(__tr2qs_ctx("The widget must be a child of this vbox","objects")); - return true; - } - ((KviTalVBox *)widget())->setStretchFactor(((QWidget *)(pObject->object())),uStretch); - return true; -} -KVSO_CLASS_FUNCTION(vbox,addStretch) -{ - CHECK_INTERNAL_POINTER(widget()) - kvs_int_t iStretch; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("stretch",KVS_PT_INT,0,iStretch) - KVSO_PARAMETERS_END(c) - ((KviTalVBox *)widget())->addStretch(iStretch); - return true; -} -KVSO_CLASS_FUNCTION(vbox,setAlignment) -{ - CHECK_INTERNAL_POINTER(widget()) - QStringList alignment; - KviKvsObject * pObject; - kvs_hobject_t hObject; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) - KVSO_PARAMETER("alignment",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,alignment) - KVSO_PARAMETERS_END(c) - pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); - CHECK_HOBJECT_IS_WIDGET(pObject) - if(((KviKvsObject_widget *)pObject)->widget()->parentWidget() != widget()) - { - c->warning(__tr2qs_ctx("The widget must be a child of this hbox","objects")); - return true; - } - - int align,sum=0; - for ( QStringList::Iterator it = alignment.begin(); it != alignment.end(); ++it ) - { - - align = 0; - for(unsigned int j = 0; j < align_num; j++) - { - if(KviQString::equalCI((*it), align_tbl[j])) - { - align=align_cod[j]; - break; - } - } - if(align) - sum = sum | align; - else - c->warning(__tr2qs_ctx("Unknown alignment: '%Q'","objects"),&(*it)); - - } - if (widget()) ((KviTalHBox *)widget())->setAlignment(((QWidget *)(pObject->object())),(Qt::Alignment)sum); - return true; -} - diff --git a/src/modules/objects/class_vbox.h b/src/modules/objects/class_vbox.h deleted file mode 100644 index 844f6ff8a..000000000 --- a/src/modules/objects/class_vbox.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _CLASS_VBOX_H_ -#define _CLASS_VBOX_H_ -//============================================================================= -// -// File : class_vbox.h -// Creation date : Fri Mar 18 14:30:48 CEST 2005 -// by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor) -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com) -// -// This program is FREE software. You can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "KviCString.h" -#include "class_widget.h" -#include "object_macros.h" - -class KviKvsObject_vbox : public KviKvsObject_widget -{ -public: - KVSO_DECLARE_OBJECT(KviKvsObject_vbox) -public: - QWidget * widget() { return (QWidget *)object(); }; -protected: - virtual bool init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams); - bool setMargin(KviKvsObjectFunctionCall *c); - bool setSpacing(KviKvsObjectFunctionCall *c); - bool setStretchFactor(KviKvsObjectFunctionCall *c); - bool addStretch(KviKvsObjectFunctionCall *c); - bool setAlignment(KviKvsObjectFunctionCall *c); - -}; - - -#endif //_CLASS_HBOX_H_ diff --git a/src/modules/objects/class_widget.cpp b/src/modules/objects/class_widget.cpp deleted file mode 100644 index 5cc799272..000000000 --- a/src/modules/objects/class_widget.cpp +++ /dev/null @@ -1,2030 +0,0 @@ -//============================================================================= -// -// File : class_widget.cpp -// Creation date : Mon Sep 11 16:35:32 CET 2000 by Krzysztof Godlewski -// -// This file is part of the KVIrc irc client distribution -// Copyright (C) 2000 Krzysztof Godlewski -// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) -// -// 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 opinion) any later version. -// -// This program is distributed in the HOPE that it will be USEFUL, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//============================================================================= - -#include "class_widget.h" -#include "class_pixmap.h" - -#include "KviMemory.h" -#include "kvi_debug.h" -#include "KviError.h" -#include "KviLocale.h" -#include "KviIconManager.h" -#include "KviWindow.h" -#include "KviApplication.h" -#include "KviMainWindow.h" -#include "KviStatusBar.h" -#include "class_painter.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef COMPILE_WEBKIT_SUPPORT - #include -#endif - -KviKvsWidget::KviKvsWidget(KviKvsObject_widget * object,QWidget * par) -:QWidget(par), m_pObject(object) -{ -} - -KviKvsWidget::~KviKvsWidget() -{ -} - -QSize KviKvsWidget::sizeHint() const -{ - QSize size=QWidget::sizeHint(); - KviKvsVariant *tipret=new KviKvsVariant(); - KviKvsVariantList params(new KviKvsVariant((kvs_int_t)size.width()),new KviKvsVariant((kvs_int_t)size.height())); - m_pObject->callFunction(m_pObject,"sizeHintRequestEvent",tipret,¶ms); - if (tipret->isArray()) - { - if (tipret->array()->size()==2) - { - kvs_int_t w,h; - if (tipret->array()->at(0)->asInteger(w) && tipret->array()->at(1)->asInteger(h))return QSize(w,h); - } - } - return QWidget::sizeHint(); -} - - - -const Qt::WidgetAttribute widgetattributes_cod[] = { - Qt::WA_OpaquePaintEvent, - Qt::WA_NoSystemBackground, - Qt::WA_PaintOnScreen, - Qt::WA_NoMousePropagation -}; - -const char * const widgetattributes_tbl[] = { - "opaquePaintEvent", - "noSystemBackground", - "paintOnScreen", - "noMousePropagation" -}; - -#define widgetattributes_num (sizeof(widgetattributes_tbl) / sizeof(widgetattributes_tbl[0])) - -const QPalette::ColorRole colorrole_cod[] = { - QPalette::Window, - QPalette::Background, - QPalette::WindowText, - QPalette::Foreground, - QPalette::Base, - QPalette::AlternateBase, - QPalette::Text, - QPalette::Button, - QPalette::ButtonText, - QPalette::BrightText, - QPalette::Highlight, - QPalette::HighlightedText -}; - -const char * const colorrole_tbl[] = { - "Window", - "Background", - "WindowText", - "Foreground", - "Base", - "AlternateBase", - "Text", - "Button", - "ButtonText", - "BrightText", - "Highlight", - "HighlightedText" -}; - -#define colorrole_num (sizeof(colorrole_tbl) / sizeof(colorrole_tbl[0])) - - -const Qt::WindowType widgettypes_cod[] = { - Qt::Window, - Qt::Dialog, - Qt::Popup, - Qt::Desktop, - Qt::WindowTitleHint, - Qt::WindowStaysOnTopHint, - Qt::WindowSystemMenuHint, - Qt::WindowMinimizeButtonHint, - Qt::WindowMaximizeButtonHint, - Qt::SubWindow, - Qt::FramelessWindowHint -}; - - -const char * const widgettypes_tbl[] = { - "Window", - "Dialog", - "Popup", - "Desktop", - "Title", - "StaysOnTop", - "SysMenu", - "Minimize", - "Maximize", - "Subwindow", - "FramelessWindow" -}; - - -#define widgettypes_num (sizeof(widgettypes_tbl) / sizeof(widgettypes_tbl[0])) - - -#define QT_WIDGET_TABFOCUS Qt::TabFocus -#define QT_WIDGET_CLICKFOCUS Qt::ClickFocus -#define QT_WIDGET_STRONGFOCUS Qt::StrongFocus -#define QT_WIDGET_NOFOCUS Qt::NoFocus -/* - @doc: widget - @keyterms: - widget object class - @title: - widget class - @type: - class - @short: - Base class for all widgets - @inherits: - [class]object[/class] - @description: - This object class is the rappresentation of a widget. - All the other widget-type classes inherit from this one. - @functions: - !fn: $show() - Shows this widget and the children. - See also [classfnc]$hide[/classfnc]() and [classfnc]$isVisible[/classfnc]. - !fn: $hide() - Hides this widget (and conseguently all the children). - See also [classfnc]$show[/classfnc]() and [classfnc]$isVisible[/classfnc]. - !fn: $repaint() - Repaints the widget directly by calling [classfnc]$paintEvent[/classfnc]() immediately. - !fn: $update([,,,]) - Updates enterily the widget or a rectangle. - This function does not cause an immediate [classfnc]$paintEvent[/classfnc](); instead it schedules a paint event for processing when KVIrc returns to the main event loop. - !fn: $x() - Returns the x coordinate of the upper-left corner - of this widget relative to the parent widget, - or to the desktop if this widget is a toplevel one. - !fn: $y() - Returns the y coordinate of the uspper-left corner - of this widget relative to the parent widget, - or to the desktop if this widget is a toplevel one. - !fn: $width() - Returns the width of this widget in pixels. - !fn: $height() - Returns the height of this widget in pixels. - !fn: $geometry() - Returns the widget geometry in this form:[br] - x, y, width, height. - !fn: $setGeometry(,[,,]) - Sets the geometry of this widget. and are relative - to the parent widget or to the desktop (if this widget is - a toplevel one). All the parameters are in pixels. - !fn: $setMinimumWidth() - Sets the minimum width of this widget to . - The user will not be able to resize the widget to a smaller - value. This value is also used by the [class:layout]layout class[/class]. - !fn: $setMinimumHeight() - Sets the minimum height of this widget to . - The user will not be able to resize the widget to a smaller - value. This value is also used by the [class:layout]layout class[/class]. - !fn: $setMaximumWidth() - Sets the maximum width of this widget to . - The user will not be able to resize the widget to a bigger - value. This value is also used by the [class:layout]layout class[/class]. - !fn: $setMaximumHeight() - Sets the maximum height of this widget to . - The user will not be able to resize the widget to a bigger - value. This value is also used by the [class:layout]layout class[/class]. - !fn: $move([,]) - Moves this widget to the coordinate and relative to its - parent widget (or the desktop if this widget is a toplevel one). - This is equivalent to [classfnc]$setGeometry[/classfnc](,, - [classfnc]$width[/classfnc](),[classfnc]$height[/classfnc]()). - !fn: $resize(,[height]) - Changes the widget's width to and height to . - See also [classfnc]$setGeometry[/classfnc](). - !fn: $isEnabled() - Returns '1' if the widget is enabled, '0' otherwise. - See also [classfnc:widget]$setEnabled[/classfnc](). - !fn: $setEnabled() - Sets the widget state to enabled or disabled if is 1 or 0 respectively. - A disabled widget does not receive keyboard nor mouse input. - !fn: $setWindowTitle() - Sets the title of this widget to . - This is meaningful for toplevel widgets only. - !fn: $setToolTip() - Set the tooltip of this widget; the text can contain HTML formatting. - !fn: $windowTitle() - Returns the title text of this widget. - !fn: $isTopLevel() - Returns '1' if this widget is a toplevel (parentless) one, - '0' otherwise. - !fn: $isVisible() - Returns '1' if this widget is currently visible (read: is managed - by the window manager and displayed by the X server; the widget - may be hidden behind other widgets). If the widget is not visible - this function returns '0'. - See also [classfnc]$show[/classfnc]() and [classfnc]$hide[/classfnc](). - !fn: $raise() - Moves this widget to the top of the stack of the widgets relative - to its parent. See also [classfnc]$lower[/classfnc]. - !fn: $lower() - Moves this widget to the bottom of the stack of the widgets relative - to its parent. See also [classfnc]$raise[/classfnc] - !fn: $hasFocus() - Returns '1' if this widget has the keyboard focus. - See also [classfnc]$setFocus[/classfnc]. - !fn: $setFocus() - Sets this widget to be the one that receives keyboard events. - See also [classfnc]$hasFocus[/classfnc] - !fn: $parentWidget() - Returns the object id of the parent widget, or '0' if this - widget is a toplevel one. - !fn: $backgroundColor() - Returns the background color of this widget in hexadecimal - html-like format. For example, for a black bacground you will get - the string "000000", for a red one, "FF0000", for a white one - "FFFFFF". See also [classfnc]$setBackgroundColor[/classfnc]() - !fn: $setBackgroundColor(,[geen:integer],[blue:integer]) - Sets the background color of this widget to :valid values are: - - hex string: must be a string with 6 hexadecimal digits (like the ones used to - specify colors in html pages). The first two digits specify - the RED component, the third and fourth digit specify the GREEN component - and the last two specify the BLUE component. - For example "FFFF00" means full red, full green and no blue that gives - a yellow color, "808000" designates a brown color (dark yellow), - "A000A0" is a kind of violet. - - array(red:integer,green:integer,blue:integer) - - red:integer,green:integer,blue:integer. - See also [classfnc]$foregroundColor[/classfnc]. - !fn: $setForegroundColor(,[geen:integer],[blue:integer]) - Sets the foreground color of this widget to :valid values are: - - hex string: must be a string with 6 hexadecimal digits (like the ones used to - specify colors in html pages). The first two digits specify - the RED component, the third and fourth digit specify the GREEN component - and the last two specify the BLUE component. - For example "FFFF00" means full red, full green and no blue that gives - a yellow color, "808000" designates a brown color (dark yellow), - "A000A0" is a kind of violet. - - array(red:integer,green:integer,blue:integer) - - red:integer,green:integer,blue:integer. - See also [classfnc]$foregroundColor[/classfnc]. - !fn: $foregroundColor() - Returns the foreground color of this widget in hexadecimal - html-like format. - See also [classfnc]$setForegroundColor[/classfnc]. - !fn: $setMouseTracking() - Enables or disables the mouse tracking if is '1' or '0' respectively. - When mouse tracking is enabled you will receive mouse move events - even if no button is pressed, otherwise you will receive it only - when a mouse button is being pressed (so after a mousePressEvent). - !fn: $mousePressEvent(